Вручную вызвать отчет об ошибке электронной почты Django
отчеты об ошибках Django обрабатывает необработанные исключения, отправляя электронное письмо, и (необязательно) показывает пользователю хорошую страницу ошибок 500.
Это работает очень хорошо, но в некоторых случаях я хотел бы позволить пользователям продолжать свой бизнес бесперебойно, но все еще есть Django отправить мне сообщение об ошибке электронной почты об исключении.
Итак, в основном: могу ли я вручную отправить отчет об ошибке электронной почты, даже если я поймаю исключение?
конечно, я хотел бы чтобы избежать создания сообщения об ошибке вручную.
4 ответов
вы можете использовать следующий код, чтобы отправить вручную письмо о request
исключение e
:
import sys
import traceback
from django.core import mail
from django.views.debug import ExceptionReporter
def send_manually_exception_email(request, e):
exc_info = sys.exc_info()
reporter = ExceptionReporter(request, is_email=True, *exc_info)
subject = e.message.replace('\n', '\n').replace('\r', '\r')[:989]
message = "%s\n\n%s" % (
'\n'.join(traceback.format_exception(*exc_info)),
reporter.filter.get_request_repr(request)
)
mail.mail_admins(
subject, message, fail_silently=True,
html_message=reporter.get_traceback_html()
)
вы можете проверить его в таком виде:
def test_view(request):
try:
raise Exception
except Exception as e:
send_manually_exception_email(request, e)
просто настройте простой обработчик журнала в своих настройках.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
'app': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
и тогда, на ваш взгляд, вы можете сделать что угодно
import logging
logger = logging.getLogger('app')
def some_view(request):
try:
# something
if something_wnet_wrong:
logger.error('Something went wrong!')
return some_http_response
except:
#something else
logger.error(sys.exc_info(), request)
return some_other_response
Если вы хотите подробный отчет об ошибках, вы можете попробовать как то так.
Вам также нужно позаботиться о конфиденциальную информацию.
Да, вы можете вручную отправить отчет об ошибке электронной почты, даже если вы поймаете исключение.
есть несколько способов, вы можете пойти об этом.
- вы можете использовать существующую конфигурацию регистратора по умолчанию (и связанную с ней конфигурацию обработчика, документированную здесь) для Django.запрос, который отправляет все сообщения об ошибках обработчику mail_admins, который отправляет все, что зарегистрировано с журналом.ошибка от django.запрос при отладке false как email с использованием AdminEmailHandler, чья существующая точка вызова находится в handle_uncaught_exception.
- вы можете добавить дополнительную конфигурацию регистратора, которая использует тот же обработчик, чтобы поймать ваше исключение раньше, чем django.журнал запросов и вызовов.ошибка ранее.
- вы можете подкласс django.запрос, в частности handle_uncaught_exception.
- вы можете использовать настраиваемое промежуточное ПО (например, StandardExceptionMiddleware) или ExceptionMiddleware
- вы можете вручную вызвать содержимое emit в
AdminEmailHandler
или по почте.mail_admins напрямую.
из этих вариантов Вариант 4, по-видимому, наиболее часто выполняется.
на основе дополнительной информации в вашем комментарии ниже приведен пример кода 2.
сначала код, который будет добавлен в view
from django.http import HttpResponse
import logging
logger = logging.getLogger(__name__)
def my_view(request):
try:
result = do_something()
return HttpResponse('<h1>Page was found' + result + '</h1>')
except Exception:
# Can have whatever status_code and title you like, but I was just matching the existing call.
logger.error('Internal Server Error: %s', request.path,
exc_info=sys.exc_info(),
extra={
'status_code': 500,
'request': request
}
)
return HttpResponse('<h1>Page was found, and exception was mailed to admins.</h1>')
Это на основании Django документация для просмотра записи и и введение в ведение журнала Django, но не был протестирован.
затем дополнительная конфигурация регистратора добавляется к записи регистраторов (согласно здесь)
'nameofdjangoapplicationgoeshere': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
Я в основном использую этот шаблон со стандартной отчетностью об ошибках.
import logging
logger = logging.getLogger('django.request')
#code block in view
try:
#code that can raise exception
except:
logger.exception('Information')
#continue as nothing happend
он вызовет встроенный отчет об ошибках и лесоруб.исключение поймает кадр стека. https://docs.djangoproject.com/en/1.8/topics/logging/#making-logging-calls
edit:
Я заметил, что в письме отсутствует некоторая информация, и для получения точной обратной связи можно использовать встроенное следующее:
logger.exception('Internal Server Error: %s', request.path,
extra={'status_code': 500, 'request': request})
Подробнее найдено здесь: как Отправить журнал исключений django вручную?