我在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',
},
},
}
此外,我还通过supervisord将sticout和sticr of gunicorn记录到两个单独的文件中。
我的问题是并非所有错误都出现在Django日志中。例如,有一种情况我在模型的保存函数中有一个简单的.get()
查询,它在管理页面中引发了DoesNotExist
异常。在任何Django日志中都没有显示此异常,我只能看到nginx日志中的500个POST请求。
当我尝试在本地计算机上使用调试模式时,它会生成详细的错误页面,但是如果我无法在本地计算机中重现错误怎么办?
为什么500个错误会在Django中无声地消失,我该如何解决?
//我知道Sentry能够报告此类异常错误,我正在寻找一种不涉及使用外部服务的方法。
答案 0 :(得分:3)
我调试了这个案例,它是两件事的组合:
SERVER_EMAIL
,Django会从root@localhost
发送管理员电子邮件。我使用的SMTP提供商(Mandrill)默默地阻止来自此类地址的所有电子邮件,因此我从未收到过电子邮件,也没有收到Mandrill的任何日志。解决方案是将SERVER_EMAIL
指定为真实地址,并使用mail_admins()
测试管理员电子邮件发送。
django.security
和django.request
记录器默认设置为不传播,因此我的根记录器''
没有捕获它们。解决方案是重新指定它们并将传播设置为True。这样他们既可以发送电子邮件,也可以在日志文件中看到。
我的工作记录器配置如下:
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,
},
},
}
答案 1 :(得分:0)
从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)
我看到了两种可能性:
settings.DEBUG_PROPAGATE_EXCEPTIONS
是True
'loggers': { '': { ...
的记录器的定义不适用于django
级别的错误