Я использую отчет об ошибках django по электронной почте. Обычно это очень полезная функция, за исключением того, что теперь у нас есть 5 минут простоя базы данных, и я получил 2000 писем. Есть ли промежуточное программное обеспечение, которое поможет мне уменьшить количество электронных писем, которые django может отправлять за минуту?
Как разобрать сообщения об ошибках Django
Ответ 1
Используя отличный ответ 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
. Если вы посмотрите в документации системы ведения журнала, это, вероятно, может быть достигнуто чистым способом (?) Путем реализации протокола протоколирования.
Ответ 2
Я ограничил электронные письма до 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)
Ответ 3
Один из вариантов заключается в переключении на ErrorStack для сообщения об ошибках. Я написал приложение django, чтобы сделать его глупо-простым для интеграции в ваш проект.
Ответ 4
Я предполагаю, что время простоя базы данных не было преднамеренным, и в этом случае вы, вероятно, должны были бы поместить ваш процесс Django в какой-то режим обслуживания или отключен в автономном режиме?
В противном случае обычное почтовое приложение django-mailer, которое могло бы помочь вам просто потому, что оно хранит исходящую почту в вашей базе данных и, таким образом, будет не удалось:)
Если вам действительно нужно оценить лимит, было бы лучше сделать это в вашем MTA. Это может означать возможность просто закрыть часть процесса MTA, ответственную за отправку почты или что-то экзотическое, например, используя этот патч для qmail для дросселирования входящих подключений как средства борьбы со спамом
Ответ 5
возможно страница Nagios на хлопании стоит прочитать