169 | | subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path) |
170 | | try: |
171 | | request_repr = repr(request) |
172 | | except: |
173 | | request_repr = "Request repr() unavailable" |
174 | | message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr) |
175 | | mail_admins(subject, message, fail_silently=True) |
| 177 | |
| 178 | # Where settings.ERROR_EMAIL_RATE_LIMIT > 0, limit to one duplicate |
| 179 | # email per ERROR_EMAIL_RATE_LIMIT seconds. Use cache if available, |
| 180 | # otherwise use local memory, limited to ERROR_EMAIL_KEY_LIMIT. |
| 181 | # If using cache, prefix keys with ERROR_EMAIL_CACHE_PREFIX. |
| 182 | |
| 183 | # Note: none of the above settings are required! |
| 184 | |
| 185 | tb = self._get_traceback(exc_info) |
| 186 | |
| 187 | # Track duplicate errors |
| 188 | duplicate = False |
| 189 | rate = getattr(settings, 'ERROR_EMAIL_RATE_LIMIT', 0) # seconds |
| 190 | if rate > 0: |
| 191 | key = md5(tb).hexdigest() |
| 192 | prefix = getattr(settings, 'ERROR_EMAIL_CACHE_PREFIX', 'ERROR_EMAIL') |
| 193 | # Test the cache works |
| 194 | cache_key = '%s_%s' % (prefix, key) |
| 195 | try: |
| 196 | cache.set(prefix, 1, 1) |
| 197 | use_cache = cache.get(prefix) == 1 |
| 198 | except: |
| 199 | use_cache = False |
| 200 | if use_cache: |
| 201 | duplicate = cache.get(cache_key) == 1 |
| 202 | cache.set(cache_key, 1, rate) |
| 203 | else: |
| 204 | min_date = datetime.now() - timedelta(seconds=rate) |
| 205 | max_keys = getattr(settings, 'ERROR_EMAIL_KEY_LIMIT', 100) |
| 206 | duplicate = (key in self._errors and self._errors[key] >= min_date) |
| 207 | self._errors = dict(filter(lambda x: x[1] >= min_date, |
| 208 | sorted(self._errors.items(), |
| 209 | key=lambda x: x[1]))[0-max_keys:]) |
| 210 | if not duplicate: |
| 211 | self._errors[key] = datetime.now() |
| 212 | |
| 213 | # Send the error |
| 214 | if rate == 0 or not duplicate: |
| 215 | subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path) |
| 216 | try: |
| 217 | request_repr = repr(request) |
| 218 | except: |
| 219 | request_repr = "Request repr() unavailable" |
| 220 | message = "%s\n\n%s" % (tb, request_repr) |
| 221 | mail_admins(subject, message, fail_silently=True) |
| 222 | |