I’m using Django 1.3 with the standard Python logging. I’ve configured it to log errors to a file:
'loggers': {
'django': {
'handlers': ['logfile'],
'level': 'ERROR',
'propagate': False,
},
I also want the username of the currently logged in Django user to be logged. For that I’ve defined my own formatter with a format that includes “%(username)s” and created my own logging class (named RequestLogger) which populates the extra username attribute. The only thing left to do is to call:
logging.setLoggerClass(RequestLogger)
The question is: where should I call this? I’ve tried putting it into __init__.py (at project level) and into settings.py. Both of those work fine with the Django dev server, but when running in Apache using WSGI I get errors like this in the Apache error log:
[error] Traceback (most recent call last):
[error] File "/usr/lib/python2.7/logging/__init__.py", line 842, in emit
[error] msg = self.format(record)
[error] File "/usr/lib/python2.7/logging/__init__.py", line 719, in format
[error] return fmt.format(record)
[error] File "/usr/lib/python2.7/logging/__init__.py", line 467, in format
[error] s = self._fmt % record.__dict__
[error] KeyError: 'username'
[error] Logged from file base.py, line 209
This seems to imply that in WSGI the Django logger gets initialised before my logging.setLoggerClass() call. (It’s definitely getting called, because my own logging works and includes the username).
Rather than use a custom logging class, you can use a Filter on your handlers to do this. See this post, and this part of the docs.