Fixed #19325 - Made email backend of AdminEmailHandler configurable

This commit is contained in:
Hannes Struss 2012-11-19 18:57:40 +01:00
parent 1f1f60d12f
commit f9891f2087
5 changed files with 69 additions and 3 deletions

View File

@ -588,6 +588,7 @@ answer newbie questions, and generally made Django that much better:
Gasper Zejn <zejn@kiberpipa.org> Gasper Zejn <zejn@kiberpipa.org>
Jarek Zgoda <jarek.zgoda@gmail.com> Jarek Zgoda <jarek.zgoda@gmail.com>
Cheng Zhang Cheng Zhang
Hannes Struß <x@hannesstruss.de>
A big THANK YOU goes to: A big THANK YOU goes to:

View File

@ -3,6 +3,7 @@ import traceback
from django.conf import settings from django.conf import settings
from django.core import mail from django.core import mail
from django.core.mail import get_connection
from django.views.debug import ExceptionReporter, get_exception_reporter_filter from django.views.debug import ExceptionReporter, get_exception_reporter_filter
@ -76,9 +77,10 @@ class AdminEmailHandler(logging.Handler):
request data will be provided in the email report. request data will be provided in the email report.
""" """
def __init__(self, include_html=False): def __init__(self, include_html=False, email_backend=None):
logging.Handler.__init__(self) logging.Handler.__init__(self)
self.include_html = include_html self.include_html = include_html
self.email_backend = email_backend
def emit(self, record): def emit(self, record):
try: try:
@ -110,7 +112,12 @@ class AdminEmailHandler(logging.Handler):
message = "%s\n\n%s" % (stack_trace, request_repr) message = "%s\n\n%s" % (stack_trace, request_repr)
reporter = ExceptionReporter(request, is_email=True, *exc_info) reporter = ExceptionReporter(request, is_email=True, *exc_info)
html_message = self.include_html and reporter.get_traceback_html() or None html_message = self.include_html and reporter.get_traceback_html() or None
mail.mail_admins(subject, message, fail_silently=True, html_message=html_message) mail.mail_admins(subject, message, fail_silently=True,
html_message=html_message,
connection=self.connection())
def connection(self):
return get_connection(backend=self.email_backend)
def format_subject(self, subject): def format_subject(self, subject):
""" """

View File

@ -440,7 +440,7 @@ Handlers
Django provides one log handler in addition to those provided by the Django provides one log handler in addition to those provided by the
Python logging module. Python logging module.
.. class:: AdminEmailHandler([include_html=False]) .. class:: AdminEmailHandler(include_html=False, email_backend=None)
This handler sends an email to the site admins for each log This handler sends an email to the site admins for each log
message it receives. message it receives.
@ -476,6 +476,23 @@ Python logging module.
sensitive information to be filtered out of error reports -- learn more on sensitive information to be filtered out of error reports -- learn more on
:ref:`Filtering error reports<filtering-error-reports>`. :ref:`Filtering error reports<filtering-error-reports>`.
.. versionadded:: 1.5
By setting the ``email_backend`` argument of ``AdminEmailHandler``, the
:ref:`email backend <topic-email-backends>` that is being used by the
handler can be overridden, like this::
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'email_backend': 'django.core.mail.backends.filebased.EmailBackend',
}
},
By default, an instance of the email backend specified in
:setting:`EMAIL_BACKEND` will be used.
.. _Sentry: http://pypi.python.org/pypi/sentry .. _Sentry: http://pypi.python.org/pypi/sentry

View File

@ -1,8 +1,15 @@
import logging import logging
from django.conf import settings from django.conf import settings
from django.core.mail.backends.base import BaseEmailBackend
class MyHandler(logging.Handler): class MyHandler(logging.Handler):
def __init__(self): def __init__(self):
logging.Handler.__init__(self) logging.Handler.__init__(self)
self.config = settings.LOGGING self.config = settings.LOGGING
class MyEmailBackend(BaseEmailBackend):
def send_messages(self, email_messages):
pass

View File

@ -15,6 +15,8 @@ from django.utils.unittest import skipUnless
from ..admin_scripts.tests import AdminScriptTestCase from ..admin_scripts.tests import AdminScriptTestCase
from .logconfig import MyEmailBackend
PYVERS = sys.version_info[:2] PYVERS = sys.version_info[:2]
# logging config prior to using filter with mail_admins # logging config prior to using filter with mail_admins
@ -305,6 +307,38 @@ class AdminEmailHandlerTest(TestCase):
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, expected_subject) self.assertEqual(mail.outbox[0].subject, expected_subject)
@override_settings(
ADMINS=(('admin', 'admin@example.com'),),
DEBUG=False,
)
def test_uses_custom_email_backend(self):
"""
Refs #19325
"""
message = 'All work and no play makes Jack a dull boy'
admin_email_handler = self.get_admin_email_handler(self.logger)
mail_admins_called = {'called': False}
def my_mail_admins(*args, **kwargs):
connection = kwargs['connection']
self.assertTrue(isinstance(connection, MyEmailBackend))
mail_admins_called['called'] = True
# Monkeypatches
orig_mail_admins = mail.mail_admins
orig_email_backend = admin_email_handler.email_backend
mail.mail_admins = my_mail_admins
admin_email_handler.email_backend = (
'regressiontests.logging_tests.logconfig.MyEmailBackend')
try:
self.logger.error(message)
self.assertTrue(mail_admins_called['called'])
finally:
# Revert Monkeypatches
mail.mail_admins = orig_mail_admins
admin_email_handler.email_backend = orig_email_backend
class SettingsConfigTest(AdminScriptTestCase): class SettingsConfigTest(AdminScriptTestCase):
""" """