Python 如何阻止Django错误电子邮件

Python 如何阻止Django错误电子邮件,python,django,error-handling,error-reporting,Python,Django,Error Handling,Error Reporting,我通过电子邮件使用django错误报告。这通常是一个非常有用的功能,除了现在我们有5分钟的数据库停机时间,我收到了2000封电子邮件。是否有任何中间件可以帮助我限制django每分钟可以发送的电子邮件数量?我认为数据库宕机不是故意的,在这种情况下,您可能应该将django进程放入某种或使其脱机 否则,通常的邮件应用程序可能会对您有所帮助,因为它将发送的邮件存储在您的数据库中,因此可能会失败:) 如果你真的需要限制费率,最好在你的MTA中这样做。这可能意味着只需关闭MTA流程中负责发送邮件的部分,

我通过电子邮件使用django错误报告。这通常是一个非常有用的功能,除了现在我们有5分钟的数据库停机时间,我收到了2000封电子邮件。是否有任何中间件可以帮助我限制django每分钟可以发送的电子邮件数量?

我认为数据库宕机不是故意的,在这种情况下,您可能应该将django进程放入某种或使其脱机

否则,通常的邮件应用程序可能会对您有所帮助,因为它将发送的邮件存储在您的数据库中,因此可能会失败:)


如果你真的需要限制费率,最好在你的MTA中这样做。这可能意味着只需关闭MTA流程中负责发送邮件的部分,或者使用类似于

的异国情调的功能,可能值得一读

一个选项是切换到类似的错误报告功能。我写了一篇文章,让你的项目更简单。

我通过以下操作将电子邮件限制在每分钟10封。这使用了我的安装所独有的redis连接功能。我建议修改递增计数器功能以满足您的需要。为了安全起见,请为此使用直接redis或memcache连接,而不要使用任何django.cache包装器

设置.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'error_email_limiter.handler.MyAdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
            },
        }
}
错误\u电子邮件\u限制器/handlers.py

class MyAdminEmailHandler(AdminEmailHandler):
    def incr_counter(self):
        c = get_redis_connection()
        key = self._redis_key()
        res = c.incr(key)
        c.expire(key, 300)
        return res

    def _redis_key(self):
        return time.strftime('error_email_limiter:%Y-%m-%d_%H:%M',
                             datetime.datetime.now().timetuple())

    def emit(self, record):
        try:
            ctr = self.incr_counter()
        except Exception:
            pass
        else:
            if ctr >= 10:
                return
        super(MyAdminEmailHandler, self).emit(record)

以Gattster的伟大答案为例,我基于django的内置缓存函数编写了一个简单的实现

# -*- coding: utf-8 -*-

from django.utils.log import AdminEmailHandler
from django.core.cache import cache


class ThrottledAdminEmailHandler(AdminEmailHandler):

    PERIOD_LENGTH_IN_SECONDS = 10
    MAX_EMAILS_IN_PERIOD = 1
    COUNTER_CACHE_KEY = "email_admins_counter"

    def increment_counter(self):
        try:
            cache.incr(self.COUNTER_CACHE_KEY)
        except ValueError:
            cache.set(self.COUNTER_CACHE_KEY, 1, self.PERIOD_LENGTH_IN_SECONDS)
        return cache.get(self.COUNTER_CACHE_KEY)

    def emit(self, record):
        try:
            counter = self.increment_counter()
        except Exception:
            pass
        else:
            if counter > self.MAX_EMAILS_IN_PERIOD:
                return
        super(ThrottledAdminEmailHandler, self).emit(record)
Django 1.9中的日志配置也已更改,因此为了使该处理程序能够工作,您需要将日志配置为:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'fully.qualified.path.to.handler.ThrottledAdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

其中更改只是将记录器的名称从
django.request
更改为
django
。如果您查看日志记录系统文档,这可能是通过实现一个更干净的(?)方法来实现的。

这听起来是一个不错的方法。你也评估过hoptoad.com吗?我需要决定选择哪种服务。不,我没有详细看hoptoad。很好。我喜欢它不依赖于redis连接,使用django的核心缓存框架
get_cache
现在被删除(从django 1.9开始)。改为使用django.core.cache导入缓存中的
,但在多个线程或进程之间似乎存在问题。。。仍在使用…Django 1.9更改了默认的日志记录配置,以便通过
Django
logger而不是
Django.request
logger记录与Django相关的内容,如下所示。如果要复制/粘贴所提供的config@Gattster,请确保已修复该问题。日志部分应该如下所示:```日志记录器':{'django':{'handlers':['mail\u admins'],'level':'ERROR','propagate':True,},}``@sebhaase可以随时更新答案以反映django@miha请随时更新答案,以反映django中的变化