Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1156

Show
Ignore:
Timestamp:
06/25/06 01:02:33
Author:
fumanchu
Message:

Much Better Logging (see #256). Apps now have their own access and error loggers (whose config entries must be at "/"), and the global access logger has been removed (although you can make one manually if you like).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/__init__.py

    r1155 r1156  
    9292    return '%02d/%s/%04d:%02d:%02d:%02d' % ( 
    9393        now.day, month, now.year, now.hour, now.minute, now.second) 
    94  
    95 _logfmt = logging.Formatter("%(message)s") 
    96  
    97 _access_log = logging.getLogger("cherrypy.access") 
    98 _access_log.setLevel(logging.INFO) 
    99  
    100 def _add_access_log_handler(handler): 
    101     if handler.level == logging.NOTSET: 
    102         handler.setLevel(logging.INFO) 
    103     if handler.formatter is None: 
    104         handler.setFormatter(_logfmt) 
    105     _access_log.addHandler(handler) 
    10694 
    10795def log_access(): 
     
    118106                'a': request.headers.get('user-agent', ''), 
    119107                } 
    120          
    121     # Create handlers if needed 
    122     if not _access_log.handlers: 
    123         if config.get('server.log_to_screen'): 
    124             _add_access_log_handler(logging.StreamHandler(sys.stdout)) 
    125         fname = config.get('log_access_file', '') 
    126         if fname: 
    127             _add_access_log_handler(logging.FileHandler(fname)) 
    128      
    129     _access_log.log(logging.INFO, s) 
     108    try: 
     109        request.app.access_log.log(logging.INFO, s) 
     110    except: 
     111        log(traceback=True) 
    130112 
    131113 
     
    133115_error_log.setLevel(logging.DEBUG) 
    134116 
    135 def _add_error_log_handler(handler): 
    136     if handler.level == logging.NOTSET: 
    137         handler.setLevel(logging.DEBUG) 
    138     if handler.formatter is None: 
    139         handler.setFormatter(_logfmt) 
    140     _error_log.addHandler(handler) 
    141  
    142117def _log_message(msg, context = '', severity = logging.DEBUG): 
    143118    """Default method for logging messages (error log). 
     
    147122    """ 
    148123     
    149     # Create handlers if needed 
    150     if not _error_log.handlers: 
    151         if config.get('server.log_to_screen'): 
    152             _add_error_log_handler(logging.StreamHandler(sys.stdout)) 
    153         fname = config.get('log_file', '') 
    154         if fname: 
    155             _add_error_log_handler(logging.FileHandler(fname)) 
    156      
    157     _error_log.log(severity, ' '.join((logtime(), context, msg))) 
     124    try: 
     125        log = request.app.error_log 
     126    except AttributeError: 
     127        log = _error_log 
     128    log.log(severity, ' '.join((logtime(), context, msg))) 
    158129 
    159130def log(msg='', context='', severity=logging.DEBUG, traceback=False): 
  • trunk/cherrypy/_cpmodpy.py

    r1151 r1156  
    1414        func() 
    1515     
    16     cherrypy.config.update({'global' : {'server.log_to_screen' : False}}) 
     16    cherrypy.config.update({'global' : {'log_to_screen' : False}}) 
    1717     
    1818    if cherrypy.engine.state == cherrypy._cpengine.STOPPED: 
  • trunk/cherrypy/_cptree.py

    r1141 r1156  
     1import logging 
     2import sys 
    13 
    24from cherrypy import config 
     
    46 
    57class Application: 
     8    """A CherryPy Application.""" 
    69     
    710    def __init__(self, root, script_name="", conf=None): 
     11        self.access_log = log = logging.getLogger("cherrypy.access.%s" % id(self)) 
     12        log.setLevel(logging.INFO) 
     13         
     14        self.error_log = log = logging.getLogger("cherrypy.error.%s" % id(self)) 
     15        log.setLevel(logging.DEBUG) 
     16         
    817        self.root = root 
    918        self.script_name = script_name 
     
    1322     
    1423    def merge(self, conf): 
     24        """Merge the given config into self.config.""" 
    1525        config.merge(self.conf, conf) 
     26         
     27        # Create log handlers as specified in config. 
     28        rootconf = self.conf.get("/", {}) 
     29        config._configure_builtin_logging(rootconf, self.access_log, "log_access_file") 
     30        config._configure_builtin_logging(rootconf, self.error_log) 
    1631     
    1732    def guess_abs_path(self): 
     
    3651 
    3752class Tree: 
    38     """A registry of mounted applications at diverse points.""" 
     53    """A registry of CherryPy applications, mounted at diverse points.""" 
    3954     
    4055    def __init__(self): 
  • trunk/cherrypy/config.py

    r1146 r1156  
    22 
    33import ConfigParser 
     4import logging 
     5_logfmt = logging.Formatter("%(message)s") 
    46import os 
     7import sys 
    58 
    69import cherrypy 
     
    6568def reset(): 
    6669    globalconf.clear() 
    67     globalconf.update(default_conf) 
     70    update(default_conf) 
    6871 
    6972def update(conf): 
     
    7881        conf = conf["global"] 
    7982    globalconf.update(conf) 
    80  
     83     
     84    _configure_builtin_logging(globalconf, cherrypy._error_log) 
     85 
     86def _add_builtin_screen_handler(log): 
     87    h = logging.StreamHandler(sys.stdout) 
     88    h.setLevel(logging.DEBUG) 
     89    h.setFormatter(_logfmt) 
     90    h._cpbuiltin = "screen" 
     91    log.addHandler(h) 
     92 
     93def _add_builtin_file_handler(log, fname): 
     94    h = logging.FileHandler(fname) 
     95    h.setLevel(logging.DEBUG) 
     96    h.setFormatter(_logfmt) 
     97    h._cpbuiltin = "file" 
     98    log.addHandler(h) 
     99 
     100def _configure_builtin_logging(conf, log, filekey="log_file"): 
     101    """Create/destroy builtin log handlers as needed from conf.""" 
     102     
     103    existing = dict([(getattr(x, "_cpbuiltin", None), x) 
     104                     for x in log.handlers]) 
     105    h = existing.get("screen") 
     106    screen = conf.get('log_to_screen') 
     107    if screen: 
     108        if not h: 
     109            _add_builtin_screen_handler(log) 
     110    elif h: 
     111        log.handlers.remove(h) 
     112     
     113    h = existing.get("file") 
     114    fname = conf.get(filekey) 
     115    if fname: 
     116        if h: 
     117            if h.baseFilename != os.path.abspath(fname): 
     118                h.close() 
     119                log.handlers.remove(h) 
     120                _add_builtin_file_handler(log, fname) 
     121        else: 
     122            _add_builtin_file_handler(log, fname) 
     123    else: 
     124        if h: 
     125            h.close() 
     126            log.handlers.remove(h) 
    81127 
    82128def get(key, default=None): 
  • trunk/cherrypy/test/test_core.py

    r1155 r1156  
    361361    cherrypy.config.update({ 
    362362        'log_to_screen': False, 
    363         'log_access_file': log_access_file, 
     363        'log_file': log_file, 
    364364        'server.protocol_version': "HTTP/1.1", 
    365365        'environment': 'production', 
     
    368368        'server.max_request_header_size': 500, 
    369369        }) 
    370     # When run via test.py, the engine is started (and the loggers created) 
    371     # before the above config.update, so we do it again manually. 
    372     import logging 
    373     cherrypy._add_error_log_handler(logging.FileHandler(log_file)) 
    374      
    375     cherrypy.tree.mount(root) 
     370    cherrypy.tree.mount(root, conf={'/': {'log_access_file': log_access_file}}) 
    376371 
    377372 

Hosted by WebFaction

Log in as guest/cpguest to create tickets