使用Django 1.5.1:
DEBUG = False
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
# root logger
'': {
'handlers': ['console'],
},
#'django.request': {
# 'handlers': ['console'],
# 'level': 'DEBUG',
# 'propagate': False,
#},
}
}
如果我取消注释注释行并调用具有1/0
的视图,则会将回溯打印到控制台:
ERROR 2013-11-29 13:33:23,102 base Internal Server Error: /comment/*******/
Traceback (most recent call last):
...
File "*****/comments/views.py", line 10, in post
1/0
ZeroDivisionError: integer division or modulo by zero
WARNING 2013-11-29 13:33:23,103 csrf Forbidden (CSRF cookie not set.): /comment/******/
[29/Nov/2013 13:33:23] "POST /comment/******/ HTTP/1.0" 500 27
但如果这些行保持注释状态,则不会向控制台打印回溯,只要:
[29/Nov/2013 13:33:23] "POST /comment/******/ HTTP/1.0" 500 27
我想如果django.request
logger没有配置,它会传播到根logger,根logger会将所有内容打印到控制台。
我没有发现任何关于django.request
的特殊信息。
为什么不起作用?
Here我读到:
Prior to Django 1.5, the LOGGING setting always overwrote the default Django logging configuration. From Django 1.5 forward, it is possible to get the project’s logging configuration merged with Django’s defaults, hence you can decide if you want to add to, or replace the existing configuration.
If the disable_existing_loggers key in the LOGGING dictConfig is set to True (which is the default) the default configuration is completely overridden. Alternatively you can redefine some or all of the loggers by setting disable_existing_loggers to False.
在django/utils/log.py
中:
# Default logging for Django. This sends an email to the site admins on every
# HTTP 500 error. Depending on DEBUG, all other log records are either sent to
# the console (DEBUG=True) or discarded by mean of the NullHandler (DEBUG=False).
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console':{
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'null': {
'class': 'django.utils.log.NullHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console'],
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'py.warnings': {
'handlers': ['console'],
},
}
}
所以在默认情况下django.request
有propagate = False
。但在我的情况下,我有'disable_existing_loggers': True
。
解决方案是防止Django配置日志记录并自行处理。幸运的是这很容易。在
settings.py
中:更新至2015年3月:Django拥有clarified他们的documentation:
对于后代和细节:解释?我认为大多数的混乱都是由于Django的explanation糟糕的
disable_existing_loggers
,它说如果是真的,“默认配置被完全覆盖”。在您自己的回答中,您发现这是不正确的;正在发生的是,Django已经配置的现有记录器被禁用了,没有被替换。Python日志记录documentation更好地解释了这一点(添加了重点):
基于Django文档,我们认为,“用我自己的日志配置覆盖默认值,而我没有指定的任何内容都将冒泡起来”。我也被这个期望绊倒了。我们期望的行为是按照替换现有的记录器(这不是真的)。取而代之的是,Django伐木工人是闭嘴而不是冒泡而来。
我们首先需要防止这些Django记录器的设置,这里Djangodocs更有用:
Django仍将使用它的记录器,但由于配置没有处理(然后禁用)它们,因此这些记录器将如预期般膨胀。使用上述设置进行简单测试:
对于Django-2.1,我发现日志配置更加简洁:
引用in the docs:
这符合^{} 的文件,其中规定:
因此,我决定不阻止Django配置日志记录。我想停止向管理员发送电子邮件,因为我使用了sentry,而且根据django文档examples,我只是将根日志配置为使用
console
和file
处理程序:结果是:
尚未在生产中测试,但它似乎将按预期工作。
好的,所以行为是“正确的”,但不是预期的。
django/conf/__init__.py:65
:正在发生的是应用默认日志配置并创建
django.request
记录器。然后,我的自定义LOGGING
配置将与disable_existing_loggers = True
一起应用,但是Python不会删除已经存在的记录器django.request
,而只会禁用它。所以我必须在我的配置中手动重新配置
django.request
记录器。:(一)相关问题 更多 >
编程相关推荐