Как регулировать сообщения об ошибках Django - PullRequest
16 голосов
/ 12 января 2010

Я использую сообщения об ошибках django по электронной почте. Обычно это очень полезная функция, за исключением того, что теперь у нас 5 минут простоя базы данных, и я получил 2000 писем. Есть ли какое-либо промежуточное программное обеспечение, которое поможет мне уменьшить количество писем, которые django может отправлять в минуту?

Ответы [ 5 ]

12 голосов
/ 17 сентября 2014

Используя отличный ответ Гаттстера в качестве примера, я написал простую реализацию, основанную на встроенных функциях кеширования 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. Если вы посмотрите в документации по системе ведения журналов, это, вероятно, может быть достигнуто более чистым (?) Путем внедрения фильтра .

.
8 голосов
/ 25 января 2012

Я ограничил количество писем до 10 в минуту, выполнив следующие действия. При этом используется функция подключения Redis, уникальная для моей установки. Я предлагаю изменить функцию incr_counter в соответствии с вашими потребностями. Для безопасности используйте для этого прямое соединение с redis или memcache, а не обертки django.cache.

settings.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,
            },
        }
}

error_email_limiter / 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)
2 голосов
/ 13 января 2010

Один из вариантов - переключиться на что-то вроде ErrorStack для сообщения об ошибках. Я написал приложение django , чтобы сделать его глупым и простым для интеграции в ваш проект.

1 голос
/ 13 января 2010

Я предполагаю, что время простоя базы данных не было преднамеренным, и в этом случае вам, вероятно, следовало бы перевести процесс Django в какой-то режим обслуживания или перевести его в автономный режим?

В противном случае, обычным почтовым приложением является django-mailer , которое могло бы помочь вам просто потому, что оно хранит исходящую почту в вашей базе данных и, таким образом, могло бы дать сбой:)

Если вам действительно нужно ограничить скорость, лучше всего это сделать в вашем MTA. Это может означать возможность просто закрыть часть процесса MTA, ответственную за отправку почты, или что-то экзотическое, например, использование этого патча для qmail для регулирования входящих соединений в качестве средства борьбы со спамом

0 голосов
/ 13 января 2010

возможно Страница Нагиоса о взмахах стоит прочитать

...