Skip to main content
 首页 » 编程设计

python之Django 没有记录所有错误

2024年08月25日30zlslch

我在 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 将 gunicorn 的 stdout 和 stderr 记录到两个单独的文件中。

我的问题是并非所有错误都显示在 Django 日志中。例如,有一种情况,当我在模型的保存函数中有一个简单的 .get() 查询时,它在管理页面中引发了一个 DoesNotExist 异常。这个异常根本没有出现在任何 Django 日志中,我只能在 nginx 日志中看到 500 的 POST 请求。

当我尝试在本地机器上使用 Debug模式时,它会生成详细的错误页面,但如果我无法在本地机器上重现错误怎么办?

为什么 500 错误在 Django 中悄无声息地消失了,我该如何解决?

//我知道 Sentry 能够报告此类异常错误,我正在寻找一种不涉及使用外部服务的方法。

请您参考如下方法:

我调试了这个案例,它是两件事的结合:

  1. 在不指定 SERVER_EMAIL 的情况下,Django 会从 root@localhost 发送管理员电子邮件。我正在使用的 SMTP 提供商 (Mandrill) 默默地阻止了来自该地址的所有电子邮件,因此我从未收到电子邮件,也没有在 Mandrill 上获得任何日志。

解决方案是将 SERVER_EMAIL 指定为真实地址,并使用 mail_admins() 测试管理员电子邮件发送。

  1. 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, 
        }, 
    }, 
}