diff --git a/django/utils/log.py b/django/utils/log.py index 1c3fe70155..a8098fcd2a 100644 --- a/django/utils/log.py +++ b/django/utils/log.py @@ -31,15 +31,16 @@ if not logger.handlers: logger.addHandler(NullHandler()) class AdminEmailHandler(logging.Handler): - def __init__(self, include_html=False): - logging.Handler.__init__(self) - self.include_html = include_html - """An exception log handler that emails log entries to site admins. If the request is passed as the first argument to the log record, request data will be provided in the email report. """ + + def __init__(self, include_html=False): + logging.Handler.__init__(self) + self.include_html = include_html + def emit(self, record): try: request = record.request @@ -53,7 +54,7 @@ class AdminEmailHandler(logging.Handler): except: subject = '%s: %s' % ( record.levelname, - record.msg + record.getMessage() ) request = None request_repr = "Request repr() unavailable." @@ -62,7 +63,7 @@ class AdminEmailHandler(logging.Handler): exc_info = record.exc_info stack_trace = '\n'.join(traceback.format_exception(*record.exc_info)) else: - exc_info = (None, record.msg, None) + exc_info = (None, record.getMessage(), None) stack_trace = 'No stack trace available' message = "%s\n\n%s" % (stack_trace, request_repr) diff --git a/tests/regressiontests/logging_tests/tests.py b/tests/regressiontests/logging_tests/tests.py index fe8b169421..76c5185e66 100644 --- a/tests/regressiontests/logging_tests/tests.py +++ b/tests/regressiontests/logging_tests/tests.py @@ -4,7 +4,10 @@ import copy from django.conf import compat_patch_logging_config from django.test import TestCase -from django.utils.log import CallbackFilter +from django.test.utils import override_settings +from django.utils.log import CallbackFilter, getLogger +from django.core import mail + # logging config prior to using filter with mail_admins @@ -115,3 +118,43 @@ class CallbackFilterTest(TestCase): f.filter("a record") self.assertEqual(collector, ["a record"]) + + +class AdminEmailHandlerTest(TestCase): + + @override_settings( + ADMINS=(('whatever admin', 'admin@example.com'),), + EMAIL_SUBJECT_PREFIX='-SuperAwesomeSubject-' + ) + def test_accepts_args(self): + """ + Ensure that user-supplied arguments and the EMAIL_SUBJECT_PREFIX + setting are used to compose the email subject. + Refs #16736. + """ + + message = "Custom message that says '%s' and '%s'" + token1 = 'ping' + token2 = 'pong' + + logger = getLogger('django.request') + # Inspired from regressiontests/views/views.py: send_log() + # ensuring the AdminEmailHandler does not get filtered out + # even with DEBUG=True. + admin_email_handler = [ + h for h in logger.handlers + if h.__class__.__name__ == "AdminEmailHandler" + ][0] + # Backup then override original filters + orig_filters = admin_email_handler.filters + admin_email_handler.filters = [] + + logger.error(message, token1, token2) + + self.assertEqual(len(mail.outbox), 1) + self.assertEqual(mail.outbox[0].to, ['admin@example.com']) + self.assertEqual(mail.outbox[0].subject, + "-SuperAwesomeSubject-ERROR: Custom message that says 'ping' and 'pong'") + + # Restore original filters + admin_email_handler.filters = orig_filters