在Django中在哪里调用logging.setLoggerClass()
我正在使用Django 1.3,并且用的是标准的Python日志记录。我已经设置好让它把错误记录到一个文件里:
'loggers': {
'django': {
'handlers': ['logfile'],
'level': 'ERROR',
'propagate': False,
},
我还想把当前登录的Django用户的用户名也记录下来。为此,我定义了自己的格式化器,格式中包含了“%(username)s”,并创建了一个自己的日志类(叫做RequestLogger
),这个类会填充额外的username
属性。现在只剩下一个步骤,就是调用:
logging.setLoggerClass(RequestLogger)
问题是:我应该在哪里调用这个?我试着把它放在__init__.py
(项目级别)和settings.py
里。这两种方法在Django开发服务器上都能正常工作,但在使用WSGI运行Apache时,我在Apache的错误日志中看到这样的错误:
[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
这似乎意味着在WSGI中,Django的日志记录器在我调用logging.setLoggerClass()
之前就已经初始化了。(这个调用确实被执行了,因为我自己的日志记录工作正常,并且包含了用户名)。
2 个回答
3
Vinay Sajip 提出的使用过滤器的解决方案完全避免了这个问题,所以我接受了他的回答。关于如何使用字典配置过滤器的文档有点不足,所以我在这里放一个例子:
LOGGING = {
...
'filters': {
'add_django_request': {
'()': 'logger.AddDjangoRequestFilter',
},
},
'handlers': {
'myhandler': {
...
'filters': ['add_django_request'],
},
},
如果有人在想,这个方法也适用于自定义的 Logger 类,只要在 .wsgi 文件中调用 setLoggerClass
,并且在 import django.core.handlers.wsgi
这一行之前(对于 Apache 来说),还有在 manage.py 文件中(对于 Django 开发服务器)。不过,过滤器的解决方案更好。