Fixed #29714 -- Allowed using ExceptionReporter subclass with AdminEmailHandler.
This commit is contained in:
parent
3c6a4fdb6d
commit
25706d7285
|
@ -7,7 +7,6 @@ from django.core import mail
|
|||
from django.core.mail import get_connection
|
||||
from django.core.management.color import color_style
|
||||
from django.utils.module_loading import import_string
|
||||
from django.views.debug import ExceptionReporter
|
||||
|
||||
request_logger = logging.getLogger('django.request')
|
||||
|
||||
|
@ -83,10 +82,11 @@ class AdminEmailHandler(logging.Handler):
|
|||
request data will be provided in the email report.
|
||||
"""
|
||||
|
||||
def __init__(self, include_html=False, email_backend=None):
|
||||
def __init__(self, include_html=False, email_backend=None, reporter_class=None):
|
||||
super().__init__()
|
||||
self.include_html = include_html
|
||||
self.email_backend = email_backend
|
||||
self.reporter_class = import_string(reporter_class or 'django.views.debug.ExceptionReporter')
|
||||
|
||||
def emit(self, record):
|
||||
try:
|
||||
|
@ -116,7 +116,7 @@ class AdminEmailHandler(logging.Handler):
|
|||
else:
|
||||
exc_info = (None, record.getMessage(), None)
|
||||
|
||||
reporter = ExceptionReporter(request, is_email=True, *exc_info)
|
||||
reporter = self.reporter_class(request, is_email=True, *exc_info)
|
||||
message = "%s\n\n%s" % (self.format(no_exc_record), reporter.get_traceback_text())
|
||||
html_message = reporter.get_traceback_html() if self.include_html else None
|
||||
self.send_mail(subject, message, fail_silently=True, html_message=html_message)
|
||||
|
|
|
@ -259,6 +259,14 @@ Internationalization
|
|||
language cookies. The default values of these settings preserve the previous
|
||||
behavior.
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
|
||||
* The new ``reporter_class`` parameter of
|
||||
:class:`~django.utils.log.AdminEmailHandler` allows providing an
|
||||
``django.views.debug.ExceptionReporter`` subclass to customize the traceback
|
||||
text sent to site :setting:`ADMINS` when :setting:`DEBUG` is ``False``.
|
||||
|
||||
Management Commands
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@ Handlers
|
|||
Django provides one log handler in addition to those provided by the
|
||||
Python logging module.
|
||||
|
||||
.. class:: AdminEmailHandler(include_html=False, email_backend=None)
|
||||
.. class:: AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None)
|
||||
|
||||
This handler sends an email to the site :setting:`ADMINS` for each log
|
||||
message it receives.
|
||||
|
@ -652,6 +652,26 @@ Python logging module.
|
|||
By default, an instance of the email backend specified in
|
||||
:setting:`EMAIL_BACKEND` will be used.
|
||||
|
||||
The ``reporter_class`` argument of ``AdminEmailHandler`` allows providing
|
||||
an ``django.views.debug.ExceptionReporter`` subclass to customize the
|
||||
traceback text sent in the email body. You provide a string import path to
|
||||
the class you wish to use, like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'class': 'django.utils.log.AdminEmailHandler',
|
||||
'include_html': True,
|
||||
'reporter_class': 'somepackage.error_reporter.CustomErrorReporter'
|
||||
}
|
||||
},
|
||||
|
||||
.. versionadded:: 3.0
|
||||
|
||||
The ``reporter_class`` argument was added.
|
||||
|
||||
.. method:: send_mail(subject, message, *args, **kwargs)
|
||||
|
||||
Sends emails to admin users. To customize this behavior, you can
|
||||
|
|
|
@ -2,6 +2,7 @@ import logging
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.mail.backends.base import BaseEmailBackend
|
||||
from django.views.debug import ExceptionReporter
|
||||
|
||||
|
||||
class MyHandler(logging.Handler):
|
||||
|
@ -13,3 +14,8 @@ class MyHandler(logging.Handler):
|
|||
class MyEmailBackend(BaseEmailBackend):
|
||||
def send_messages(self, email_messages):
|
||||
pass
|
||||
|
||||
|
||||
class CustomExceptionReporter(ExceptionReporter):
|
||||
def get_traceback_text(self):
|
||||
return 'custom traceback text'
|
||||
|
|
|
@ -16,6 +16,7 @@ from django.utils.log import (
|
|||
DEFAULT_LOGGING, AdminEmailHandler, CallbackFilter, RequireDebugFalse,
|
||||
RequireDebugTrue, ServerFormatter,
|
||||
)
|
||||
from django.views.debug import ExceptionReporter
|
||||
|
||||
from . import views
|
||||
from .logconfig import MyEmailBackend
|
||||
|
@ -431,6 +432,20 @@ class AdminEmailHandlerTest(SimpleTestCase):
|
|||
finally:
|
||||
admin_email_handler.include_html = old_include_html
|
||||
|
||||
def test_default_exception_reporter_class(self):
|
||||
admin_email_handler = self.get_admin_email_handler(self.logger)
|
||||
self.assertEqual(admin_email_handler.reporter_class, ExceptionReporter)
|
||||
|
||||
@override_settings(ADMINS=[('A.N.Admin', 'admin@example.com')])
|
||||
def test_custom_exception_reporter_is_used(self):
|
||||
record = self.logger.makeRecord('name', logging.ERROR, 'function', 'lno', 'message', None, None)
|
||||
record.request = self.request_factory.get('/')
|
||||
handler = AdminEmailHandler(reporter_class='logging_tests.logconfig.CustomExceptionReporter')
|
||||
handler.emit(record)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
msg = mail.outbox[0]
|
||||
self.assertEqual(msg.body, 'message\n\ncustom traceback text')
|
||||
|
||||
|
||||
class SettingsConfigTest(AdminScriptTestCase):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue