[英]Django not logging all errors
I have the following logging config set up in Django 1.8: 我在Django 1.8中设置了以下日志记录配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': normpath(join(DJANGO_ROOT, '../../logs', 'django.log')),
},
},
'loggers': {
'': {
'handlers': ['file'],
'propagate': True,
'level': 'DEBUG',
},
},
}
Moreover, I'm also logging the stdout and stderr of gunicorn into two separate files via supervisord. 此外,我还将通过管理员将gunicorn的stdout和stderr记录到两个单独的文件中。
My problem is that not all errors are showing up in Django logs. 我的问题是,并非所有错误都显示在Django日志中。 For example, there is a case when I had a simple
.get()
query in a model's save function, which raised a DoesNotExist
exception in the admin page. 例如,在
DoesNotExist
情况下,我在模型的保存函数中有一个简单的.get()
查询,这在管理页面中引发了DoesNotExist
异常。 This exception did not show up at all in any Django log, all I could see was the 500 in the nginx log for a POST request. 这个异常在任何Django日志中都没有出现,我所能看到的只是nginx日志中有POST请求的500。
When I tried with debug mode in local machine, it produced the detailed error page, but what if I couldn't reproduce a bug in a local machine? 当我在本地计算机上尝试调试模式时,它会产生详细的错误页面,但是如果我无法在本地计算机上重现错误,该怎么办?
Why are 500 errors silently disappearing in Django and how can I fix it? 为什么Django中会自动消失500个错误,我该如何解决?
// I know that Sentry is able to report such exception errors, I'm looking for a way which doesn't involve using an external service. //我知道Sentry能够报告此类异常错误,我正在寻找一种不涉及使用外部服务的方法。
I debugged the case, it was a combination of two things: 我调试了一下,这是两件事的结合:
SERVER_EMAIL
, Django sends admin emails from root@localhost
. SERVER_EMAIL
,Django从root@localhost
发送管理电子邮件。 The SMTP provider I'm using (Mandrill) silently blocks all emails from such address, thus I never got the emails, nor any log at Mandrill. Solution was to specify SERVER_EMAIL
to a real address and test admin email sending using mail_admins()
. 解决方案是将
SERVER_EMAIL
指定为真实地址,并使用mail_admins()
测试管理员发送的电子邮件。
django.security
and django.request
loggers are set not to propagate by default, thus my root logger ''
did not catch them. django.security
和django.request
记录器默认设置为不传播,因此我的root记录器''
没有捕获到它们。 Solution was to re-specify them and set propagate to True. 解决方案是重新指定它们并将传播设置为True。 This way they both send emails and are visible in the log files as well.
这样,他们既可以发送电子邮件,也可以在日志文件中看到它们。
My working logger configuration is the following: 我的工作记录器配置如下:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': normpath(join(DJANGO_ROOT, '../../logs', 'django.log')),
'formatter': 'verbose',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler'
}
},
'formatters': {
'verbose': {
'format': '%(asctime)s %(levelname)-8s [%(name)s:%(lineno)s] %(message)s',
},
},
'loggers': {
'': {
'handlers': ['file'],
'level': 'DEBUG',
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
'django.security': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
},
}
Reading this code from django.core.handlers.base.BaseHandler
, 从
django.core.handlers.base.BaseHandler
读取此代码,
def handle_uncaught_exception(self, request, resolver, exc_info):
"""
Processing for any otherwise uncaught exceptions (those that will
generate HTTP 500 responses). Can be overridden by subclasses who want
customised 500 handling.
Be *very* careful when overriding this because the error could be
caused by anything, so assuming something like the database is always
available would be an error.
"""
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise
logger.error('Internal Server Error: %s', request.path,
exc_info=exc_info,
extra={
'status_code': 500,
'request': request
}
)
if settings.DEBUG:
return debug.technical_500_response(request, *exc_info)
# If Http500 handler is not installed, re-raise last exception
if resolver.urlconf_module is None:
six.reraise(*exc_info)
# Return an HttpResponse that displays a friendly error message.
callback, param_dict = resolver.resolve_error_handler(500)
return callback(request, **param_dict)
I see 2 possibilities : 我看到两种可能性:
settings.DEBUG_PROPAGATE_EXCEPTIONS
is True
settings.DEBUG_PROPAGATE_EXCEPTIONS
为True
'loggers': { '': { ...
doesn't work for the errors catched at django
level 'loggers': { '': { ...
定义的记录'loggers': { '': { ...
对于在django
级别捕获的错误不起作用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.