Ticket #11565: error_emails_rate_limit.patch

File error_emails_rate_limit.patch, 3.6 KB (added by andrewmintel, 6 years ago)
  • django/core/handlers/base.py

     
     1try:
     2    from hashlib import md5
     3except ImportError:
     4    from md5 import md5
    15import sys
    26
     7from django.core.cache import cache                               
    38from django import http
    49from django.core import signals
    510from django.utils.encoding import force_unicode
     
    154159            return debug.technical_500_response(request, *exc_info)
    155160
    156161        # When DEBUG is False, send an error message to the admins.
    157         subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
     162        # To ensure we only send one email per ERROR_EMAIL_RATE_LIMIT time period                                                             
     163        # we take an md5 of the traceback and store it in the cache with a timeout.                                                           
     164        # If the value exists in the cache then we skip sending an email.                                                                     
     165        tb = self._get_traceback(exc_info)                                                                                                     
     166        key = "django_error_md5_%s" % (md5(unicode(tb).encode("utf8")).hexdigest(), )
     167
     168        # The worst case is for the cache to have failed and to be raising exceptions so we mask them all.
    158169        try:
    159             request_repr = repr(request)
     170            cache_hit = cache.get(key) is not None
    160171        except:
    161             request_repr = "Request repr() unavailable"
    162         message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
    163         mail_admins(subject, message, fail_silently=True)
     172            cache_hit = False
     173
     174        if not cache_hit:
     175            subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
     176            try:
     177                request_repr = repr(request)
     178            except:
     179                request_repr = "Request repr() unavailable"
     180            message = "%s\n\n%s" % (tb, request_repr)
     181            mail_admins(subject, message, fail_silently=True)
     182
     183            # If the error emails are being rate limited set a cache value to prevent the same email being send again
     184            if hasattr(settings, "ERROR_EMAIL_RATE_LIMIT") and settings.ERROR_EMAIL_RATE_LIMIT > 0:
     185                try:
     186                    cache.set(key, "Error Occurred!", settings.ERROR_EMAIL_RATE_LIMIT*60)
     187                except:
     188                    pass
     189
    164190        # Return an HttpResponse that displays a friendly error message.
    165191        callback, param_dict = resolver.resolve500()
    166192        return callback(request, **param_dict)
  • docs/ref/settings.txt

     
    447447
    448448Whether to use a TLS (secure) connection when talking to the SMTP server.
    449449
     450.. setting:: ERROR_EMAIL_RATE_LIMIT
     451
     452ERROR_EMAIL_RATE_LIMIT
     453----------------------
     454
     455Default: ``0``
     456
     457How often to send emails to the admins regarding errors in minutes. If set to 0 an email is send for every exception, if greater than 0 then an email is send once every ``ERROR_EMAIL_RATE_LIMIT`` minutes for each distinct traceback.
     458
     459This settings requires a configured cache backend to function correctly.
     460
    450461.. setting:: FILE_CHARSET
    451462
    452463FILE_CHARSET
Back to Top