improve logger overide

- add Logger.atoms() that facilitates log format override.
- add Logger.atoms_wrapper_class that permits custom wrapping.

fix #510
This commit is contained in:
jean-philippe serafin 2013-04-08 11:51:48 +02:00 committed by benoitc
parent 87474ffce1
commit 1911facf1a

View File

@ -202,6 +202,8 @@ class Logger(object):
access_fmt = "%(message)s" access_fmt = "%(message)s"
syslog_fmt = "[%(process)d] %(message)s" syslog_fmt = "[%(process)d] %(message)s"
atoms_wrapper_class = SafeAtoms
def __init__(self, cfg): def __init__(self, cfg):
self.error_log = logging.getLogger("gunicorn.error") self.error_log = logging.getLogger("gunicorn.error")
self.access_log = logging.getLogger("gunicorn.access") self.access_log = logging.getLogger("gunicorn.access")
@ -264,30 +266,25 @@ class Logger(object):
lvl = self.LOG_LEVELS.get(lvl.lower(), logging.INFO) lvl = self.LOG_LEVELS.get(lvl.lower(), logging.INFO)
self.error_log.log(lvl, msg, *args, **kwargs) self.error_log.log(lvl, msg, *args, **kwargs)
def access(self, resp, req, environ, request_time): def atoms(self, resp, req, environ, request_time):
""" Seee http://httpd.apache.org/docs/2.0/logs.html#combined """ Gets atoms for log formating.
for format details
""" """
if not self.cfg.accesslog and not self.cfg.logconfig:
return
status = resp.status.split(None, 1)[0] status = resp.status.split(None, 1)[0]
atoms = { atoms = {
'h': environ.get('REMOTE_ADDR', '-'), 'h': environ.get('REMOTE_ADDR', '-'),
'l': '-', 'l': '-',
'u': '-', # would be cool to get username from basic auth header 'u': '-', # would be cool to get username from basic auth header
't': self.now(), 't': self.now(),
'r': "%s %s %s" % (environ['REQUEST_METHOD'], 'r': "%s %s %s" % (environ['REQUEST_METHOD'],
environ['RAW_URI'], environ["SERVER_PROTOCOL"]), environ['RAW_URI'], environ["SERVER_PROTOCOL"]),
's': status, 's': status,
'b': resp.response_length and str(resp.response_length) or '-', 'b': resp.response_length and str(resp.response_length) or '-',
'f': environ.get('HTTP_REFERER', '-'), 'f': environ.get('HTTP_REFERER', '-'),
'a': environ.get('HTTP_USER_AGENT', '-'), 'a': environ.get('HTTP_USER_AGENT', '-'),
'T': str(request_time.seconds), 'T': str(request_time.seconds),
'D': str(request_time.microseconds), 'D': str(request_time.microseconds),
'p': "<%s>" % os.getpid() 'p': "<%s>" % os.getpid()
} }
# add request headers # add request headers
if hasattr(req, 'headers'): if hasattr(req, 'headers'):
@ -300,10 +297,21 @@ class Logger(object):
# add response headers # add response headers
atoms.update(dict([("{%s}o" % k.lower(), v) for k, v in resp.headers])) atoms.update(dict([("{%s}o" % k.lower(), v) for k, v in resp.headers]))
return atoms
def access(self, resp, req, environ, request_time):
""" See http://httpd.apache.org/docs/2.0/logs.html#combined
for format details
"""
if not self.cfg.accesslog and not self.cfg.logconfig:
return
# wrap atoms: # wrap atoms:
# - make sure atoms will be test case insensitively # - make sure atoms will be test case insensitively
# - if atom doesn't exist replace it by '-' # - if atom doesn't exist replace it by '-'
safe_atoms = SafeAtoms(atoms) safe_atoms = self.atoms_wrapper_class(self.atoms(resp, req, environ,
request_time))
try: try:
self.access_log.info(self.cfg.access_log_format % safe_atoms) self.access_log.info(self.cfg.access_log_format % safe_atoms)