Django:每次报错时自动向管理员发送邮件
Django 全局异常捕获与自动邮件告警方案
一、用Django原生配置快速实现
Django自带异常邮件通知功能,无需大量自定义代码就能搞定基础告警:
- 配置管理员与邮件参数
在settings.py中添加以下配置:
# 接收告警的管理员邮箱 ADMINS = [('管理员', 'admin@mail.com')] # 邮件发送基础配置(根据你的邮箱服务商调整) EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.mail.com' EMAIL_PORT = 587 EMAIL_HOST_USER = 'your-sender-email@mail.com' EMAIL_HOST_PASSWORD = 'your-email-password' EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = EMAIL_HOST_USER # 根据环境控制告警开关 if settings.ENVIRONMENT == 'PROD': DEBUG = False SEND_BROKEN_LINK_EMAILS = True # 开启断链告警 else: DEBUG = True
- 日志配置增强告警范围
如果需要针对特定APP或错误级别触发邮件,配置LOGGING让ERROR级日志自动发邮件:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'include_html': True, # 邮件包含HTML格式的错误详情 }, }, 'loggers': { 'django': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, 'your_app_name': { # 替换为你的项目APP名称 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, }, }
二、自定义中间件捕获所有请求异常
原生配置仅覆盖框架级500错误,自定义中间件能捕获所有请求处理过程中未捕获的异常(包括业务代码主动抛出的):
- 创建中间件文件
在你的APP目录下新建middleware.py:
from django.http import HttpResponseServerError from django.conf import settings from your_app.utils import BaseScraper # 替换为你的BaseScraper实际路径 class GlobalExceptionMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) return response def process_exception(self, request, exception): # 组装包含请求上下文的告警内容 subject = f"系统异常 - 请求路径: {request.path}" email_content = ( f"请求路径: {request.path}\n" f"请求方法: {request.method}\n" f"客户端IP: {request.META.get('REMOTE_ADDR')}\n" f"异常详情:\n{str(exception)}" ) # 按环境分发告警邮件 recipients = ["admin@mail.com"] if settings.ENVIRONMENT == 'PROD' else ["test-admin@mail.com"] BaseScraper.email_alert_for_error(subject, email_content, recipients) # 返回标准500响应(也可自定义错误页面) return HttpResponseServerError("服务器内部错误")
- 注册中间件
在settings.py的MIDDLEWARE列表中添加中间件路径:
MIDDLEWARE = [ # 其他中间件... 'your_app.middleware.GlobalExceptionMiddleware', # 建议放在中间件列表末尾 ]
三、统一处理主动抛出的异常
为避免每次主动抛异常时重复编写邮件代码,封装自定义异常类:
from django.conf import settings from your_app.utils import BaseScraper class SystemAlertError(Exception): def __init__(self, message, subject="主动触发系统告警"): super().__init__(message) self.subject = subject # 抛异常时自动触发邮件告警 self.send_alert() def send_alert(self): recipients = ["admin@mail.com"] if settings.ENVIRONMENT == 'PROD' else ["test-admin@mail.com"] BaseScraper.email_alert_for_error(self.subject, str(self), recipients)
之后在业务代码中主动抛异常时,直接使用:
# 示例:数据处理失败时抛出 raise SystemAlertError("多源数据合并失败:缺失用户ID字段")
四、方案选择建议
- 快速实现选原生配置+日志,适合基础框架错误告警
- 全覆盖请求异常选自定义中间件,能捕获业务代码未处理的异常
- 主动异常统一处理选自定义异常类,避免重复编写邮件逻辑
内容的提问来源于stack exchange,提问作者Sinha
相关产品推荐
相关产品推荐

