mirror of https://github.com/django/django.git
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.mail import get_connection
|
||||||
from django.core.management.color import color_style
|
from django.core.management.color import color_style
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
from django.views.debug import ExceptionReporter
|
|
||||||
|
|
||||||
request_logger = logging.getLogger('django.request')
|
request_logger = logging.getLogger('django.request')
|
||||||
|
|
||||||
|
@ -83,10 +82,11 @@ 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, email_backend=None):
|
def __init__(self, include_html=False, email_backend=None, reporter_class=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.include_html = include_html
|
self.include_html = include_html
|
||||||
self.email_backend = email_backend
|
self.email_backend = email_backend
|
||||||
|
self.reporter_class = import_string(reporter_class or 'django.views.debug.ExceptionReporter')
|
||||||
|
|
||||||
def emit(self, record):
|
def emit(self, record):
|
||||||
try:
|
try:
|
||||||
|
@ -116,7 +116,7 @@ class AdminEmailHandler(logging.Handler):
|
||||||
else:
|
else:
|
||||||
exc_info = (None, record.getMessage(), None)
|
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())
|
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
|
html_message = reporter.get_traceback_html() if self.include_html else None
|
||||||
self.send_mail(subject, message, fail_silently=True, html_message=html_message)
|
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
|
language cookies. The default values of these settings preserve the previous
|
||||||
behavior.
|
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
|
Management Commands
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -595,7 +595,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, 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
|
This handler sends an email to the site :setting:`ADMINS` for each log
|
||||||
message it receives.
|
message it receives.
|
||||||
|
@ -652,6 +652,26 @@ Python logging module.
|
||||||
By default, an instance of the email backend specified in
|
By default, an instance of the email backend specified in
|
||||||
:setting:`EMAIL_BACKEND` will be used.
|
: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)
|
.. method:: send_mail(subject, message, *args, **kwargs)
|
||||||
|
|
||||||
Sends emails to admin users. To customize this behavior, you can
|
Sends emails to admin users. To customize this behavior, you can
|
||||||
|
|
|
@ -2,6 +2,7 @@ import logging
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.mail.backends.base import BaseEmailBackend
|
from django.core.mail.backends.base import BaseEmailBackend
|
||||||
|
from django.views.debug import ExceptionReporter
|
||||||
|
|
||||||
|
|
||||||
class MyHandler(logging.Handler):
|
class MyHandler(logging.Handler):
|
||||||
|
@ -13,3 +14,8 @@ class MyHandler(logging.Handler):
|
||||||
class MyEmailBackend(BaseEmailBackend):
|
class MyEmailBackend(BaseEmailBackend):
|
||||||
def send_messages(self, email_messages):
|
def send_messages(self, email_messages):
|
||||||
pass
|
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,
|
DEFAULT_LOGGING, AdminEmailHandler, CallbackFilter, RequireDebugFalse,
|
||||||
RequireDebugTrue, ServerFormatter,
|
RequireDebugTrue, ServerFormatter,
|
||||||
)
|
)
|
||||||
|
from django.views.debug import ExceptionReporter
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
from .logconfig import MyEmailBackend
|
from .logconfig import MyEmailBackend
|
||||||
|
@ -431,6 +432,20 @@ class AdminEmailHandlerTest(SimpleTestCase):
|
||||||
finally:
|
finally:
|
||||||
admin_email_handler.include_html = old_include_html
|
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):
|
class SettingsConfigTest(AdminScriptTestCase):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue