Django:有没有办法从 mail_admins 日志处理程序中过滤掉 503“服务不可用”响应?

Posted

技术标签:

【中文标题】Django:有没有办法从 mail_admins 日志处理程序中过滤掉 503“服务不可用”响应?【英文标题】:Django: Is there a way to filter out 503 'service unavilable' responses from mail_admins log handler? 【发布时间】:2021-03-11 06:58:07 【问题描述】:

我用标准的“邮件管理员 500 错误”配置了 django LOGGING:

'mail_admins': 
    'level': 'ERROR',
    'filters': ['require_debug_false'],
    'class': 'django.utils.log.AdminEmailHandler'
,

当我将站点置于维护模式 (django-maintenance-mode) 时,它会正确响应匿名请求的 503“服务不可用”。当站点处于维护模式时,这会导致向管理员发送大量电子邮件。 我想“过滤掉 503 响应 IF 站点处于维护模式”以阻止洪水。 但看不到执行此操作的简单方法(例如,日志过滤器需要请求检查站点是否处于维护模式)

我知道我可以将维护错误代码更改为 400 级错误,但这似乎是非语义破解。也可以在维护期间暂停管理员电子邮件,但这需要记住破解/恢复设置文件。希望有人有一个聪明的想法如何简单地实现这一点,没有黑客。

【问题讨论】:

【参考方案1】:

您可以在 settings.py 的 LOGGING 中简单地创建过滤器“require_not_maintenance_mode_503”,然后在处理程序“ma​​il_admins”中添加过滤器。这将防止在 503 错误时发送电子邮件。例如:

    LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'filters': 
        'require_not_maintenance_mode_503': 
            '()': 'maintenance_mode.logging.RequireNotMaintenanceMode503',
        ,
    ,
    'formatters': 
        'verbose': 
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        ,
        'simple': 
            'format': '%(levelname)s %(message)s'
        ,
    ,
    'handlers': 
        'mail_admins': 
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['require_not_maintenance_mode_503'],
            'formatter': 'simple'
        ,
    ,
    'loggers': 
        'django': 
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        ,
        'django.request': 
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        ,
    ,

【讨论】:

谢谢 - 如果可行,我会尝试并将其标记为正确答案。非常感谢! 如何在您的环境中通过解决方案的测试?需要什么帮助吗?在我的环境中完美运行。 这工作得很好,并记录在这里:github.com/fabiocaccamo/django-maintenance-mode#logging 请注意,v.0.16.2 解决了问题,因此无论站点如何进行维护,过滤器现在都可以工作。感谢@schum 和所有软件包贡献者。【参考方案2】:

实际上,我可以建议一种 hacky 方法。您可以创建一个继承 AdminEmailHandler 类的类。

class CustomAdminEmailHandler(AdminEmailHandler):
    def send_mail(self, subject, message, *args, **kwargs):
        if 'service unavailable' in subject.lower(): # Not sure about the condition, you can find the correct one by debugging.
            super().send_email(subject, message, *args, **kwargs)

不要忘记在设置中将 mail_admins 的类更改为新的。

【讨论】:

哦,是的。那是个好主意。但是仍然无法在没有访问请求对象的情况下检查系统是否处于维护模式。我不想普遍阻止此类错误,仅阻止那些故意将站点置于维护模式的错误。感谢您的想法 - 值得细细品味。【参考方案3】:

您可以在站点处于维护模式时设置 DEBUG=TRUE ——我的意思是,它就在您的日志记录配置中。 哦!

仍然需要修改设置文件,然后在退出维护时记得将其修改回来。有点hacky,但看起来很简单。

【讨论】:

以上是关于Django:有没有办法从 mail_admins 日志处理程序中过滤掉 503“服务不可用”响应?的主要内容,如果未能解决你的问题,请参考以下文章

在mail_admins()中发送EmailMultiAlternatives

Django——有没有办法从模板中引用/获取当前页面 URL? [复制]

Django:有没有办法从单元测试中计算 SQL 查询?

有没有办法在 ubuntu 上同时使用 Pytion3、django2.0.2 和 MySql?

有没有办法使用 Django REST 框架中的可浏览 API 上传文件?

有没有办法将 Django 模型查询集转换为模板中的 json 或 json 字符串?