You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django:每次报错时自动向管理员发送邮件

Django 全局异常捕获与自动邮件告警方案

一、用Django原生配置快速实现

Django自带异常邮件通知功能,无需大量自定义代码就能搞定基础告警:

  1. 配置管理员与邮件参数
    在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
  1. 日志配置增强告警范围
    如果需要针对特定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错误,自定义中间件能捕获所有请求处理过程中未捕获的异常(包括业务代码主动抛出的):

  1. 创建中间件文件
    在你的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("服务器内部错误")
  1. 注册中间件
    在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:15:34