Django配置AdminEmailHandler过滤规则后仍持续发送报错邮件如何解决
问题根因
你遇到的问题核心来自三个常见配置误区:
- 错误日志来源不匹配:你要屏蔽的
Invalid HTTP_HOST header属于DisallowedHost异常,Django默认将该类错误输出到django.security.DisallowedHostlogger,而非你配置的django.requestlogger,你当前加在django.request链路上的过滤器无法作用到实际产生告警的日志。 - 过滤器匹配逻辑缺陷:Django记录日志多采用参数化模板形式,
record.msg存储的是带占位符的模板字符串,直接判断record.msg的内容可能因为占位符存在导致匹配失效。 - 配置未正确覆盖默认规则:如果你的
LOGGING配置中disable_existing_loggers保留了默认值True,会导致自定义的过滤器、handler无法正确作用到Django默认的logger链路。
解决方案
1. 修正日志配置
调整你的LOGGING配置,首先确保配置合并开关打开,其次覆盖非法Host对应的logger规则:
LOGGING = { # 必须设为False,保留Django默认logger的同时加载自定义配置 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', }, 'silence_invalid_header': { '()': 'mysite.logger_utils.SilenceInvalidHttpHostHeader' }, }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false', 'silence_invalid_header'], 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, # 新增DisallowedHost日志规则,直接拦截不上报邮件 'django.security.DisallowedHost': { 'handlers': ['console'], 'propagate': False, } } }
2. 优化过滤器匹配逻辑
修改过滤器实现,使用拼接完成的完整日志内容做匹配:
import logging class SilenceInvalidHttpHostHeader(logging.Filter): def filter(self, record): # 调用getMessage()获取参数填充后的完整日志文本,避免模板占位符导致匹配失败 full_msg = record.getMessage() return 'Invalid HTTP_HOST header' not in full_msg
3. 验证生效
重启Django服务后,手动构造非法Host请求验证:
curl -H "Host: test-invalid-host.com" http://你的服务地址
确认没有触发告警邮件即可。
内容的提问来源于stack exchange,提问作者dabadaba
相关产品推荐
相关产品推荐

