Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throttle Django error emails

I use django error reporting via email. It is normally a very helpful feature, except that now we have 5 minutes of database downtime and I got 2000 emails. Is there any middleware that will help me throttle the number of emails django can send out per minute?

like image 739
Gattster Avatar asked Jan 12 '10 20:01

Gattster


1 Answers

Using Gattster's great answer as an example, I wrote a simple implementation based on django's built-in cache functions.

# -*- 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)

And the logging configuration has been changed in Django 1.9 as well, so in order for this handler to work, you need to configure logging as:

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

where the change is only to change the name of the logger from django.request to django. If you look in the logging system documentation, this could probably be achieved in a cleaner (?) way by implementing a logging filter.

like image 194
Dennis Golomazov Avatar answered Sep 28 '22 04:09

Dennis Golomazov