Déclencher manuellement le rapport D'erreur D'email Django
Django error reporting gère les exceptions non récupérées en envoyant un email, et (optionnellement) montre à l'utilisateur une page d'erreur nice 500.
Cela fonctionne très bien, mais dans quelques cas, j'aimerais permettre aux utilisateurs de continuer leur activité, sans interruption, mais encore Django m'envoyer l'e-mail de rapport d'erreur à propos de l'exception.
donc essentiellement: Est-ce que je peux envoyer manuellement un rapport d'erreur de courriel même si j'attrape l'exception?
bien sûr, j'aimerais éviter de générer manuellement le courriel de rapport d'erreur.
4 réponses
vous pouvez utiliser le code suivant pour envoyer manuellement un email au sujet d'un request
et une exception 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()
)
vous pouvez le tester dans une vue comme celle-ci:
def test_view(request):
try:
raise Exception
except Exception as e:
send_manually_exception_email(request, e)
il suffit de configurer un gestionnaire de journalisation simple dans vos paramètres.
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,
},
}
}
et alors, à votre avis, vous ne pouvez rien faire
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
si vous voulez un rapport d'erreur détaillé, vous pouvez essayer quelque chose comme ceci .
Vous avez également besoin de prendre soin de "1519110920 des" informations sensibles .
Oui vous pouvez envoyer manuellement un rapport d'erreur par courriel même si vous avez saisi l'exception.
il y a plusieurs façons d'y arriver.
- vous pouvez utiliser la configuration par défaut de l'enregistreur (et sa configuration de gestionnaire associée, documentée ici ) pour django.requête qui envoie tous les messages d'erreur au gestionnaire mail_adms, qui envoie tout ce qui est enregistré avec log.erreur de django.demande lors de la debug est faux en tant qu'email en utilisant AdminEmailHandler , dont le point d'appel existant est handle_uncaught_exception .
- vous pouvez ajouter une configuration logger supplémentaire qui utilise le même gestionnaire, pour attraper votre exception plus tôt que django.demande et journal des appels.erreur plus tôt.
- vous pouvez classer django.demande, plus précisément handle_uncaught_exception.
- vous pouvez utiliser un middleware ( par exemple StandardExceptionMiddleware ) ou ExceptionMiddleware
- vous pouvez appeler manuellement le contenu d'emit dans
AdminEmailHandler
ou par la poste.mail_admins directement.
parmi ces options, L'Option 4 semble être la plus courante.
D'après les renseignements supplémentaires contenus dans votre commentaire, un exemple de code 2 est présenté ci-dessous.
First le code qui serait ajouté pour voir
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>')
basé sur la documentation Django pour l'écriture de vue et et l'introduction à la journalisation de Django , mais n'a pas été testé.
puis la configuration de logger supplémentaire est ajoutée à l'entrée de loggers (selon ici )
'nameofdjangoapplicationgoeshere': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
j'utilise principalement Ce modèle avec le rapport d'erreur standard.
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
il va déclencher le rapport d'erreur intégré et enregistreur.exception va attraper le cadre de pile. https://docs.djangoproject.com/en/1.8/topics/logging/#making-logging-calls
edit:
j'ai remarqué que certaines informations manquaient dans l'email et pour obtenir un retraçage exact car le construit dans ce qui suit peut être utilisé à la place:
logger.exception('Internal Server Error: %s', request.path,
extra={'status_code': 500, 'request': request})
plus d'informations trouvées ici: comment envoyer le journal des exceptions django manuellement?