Djangoエラーレポート 電子メールを送信することでキャッチされなかった例外を処理し、(オプションで)ユーザーにNice500エラーページを表示します。
これは非常にうまく機能しますが、いくつかの例では、ユーザーがビジネスを中断することなく続行できるようにしたいのですが、それでもDjango例外に関するメールエラーレポートを送ってください。
つまり、基本的に、例外をキャッチした場合でも、手動で電子メールエラーレポートを送信できますか?
もちろん、エラーレポートの電子メールを手動で生成することは避けたいと思います。
次のコードを使用して、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
詳細なエラーレポートが必要な場合は、 このようなもの を試すことができます。
機密情報 にも注意する必要があります。
はい、例外をキャッチした場合でも、手動で電子メールエラーレポートを送信できます。
これについては、いくつかの方法があります。
AdminEmailHandler
またはmail.mail_adminsのemitの内容を手動で直接呼び出すことができます。これらのオプションのうち、オプション4が最も一般的に行われているようです。
コメントの追加情報に基づいて、2のコード例を以下に示します。
まず、表示するために追加されるコード
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
組み込みのエラー報告がトリガーされ、logger.exceptionがスタックフレームをキャッチします。 https://docs.djangoproject.com/en/1.8/topics/logging/#making-logging-calls
編集:
電子メールにいくつかの情報が欠落していることに気付きました。代わりに、組み込みの次のものを使用できるため、正確なトレースバックを取得できます。
logger.exception('Internal Server Error: %s', request.path,
extra={'status_code': 500, 'request': request})
詳細はこちら: Django例外ログを手動で送信する方法
@JuniorCompressorの回答に基づいて、これは私が使用するコードです。
import sys
from Django.core import mail
from Django.views.debug import ExceptionReporter
def send_exception_email(request, exception, subject_prefix=''):
exc_info = sys.exc_info()
reporter = ExceptionReporter(request, *exc_info, is_email=True)
def exception_name():
if exc_info[0]:
return exc_info[0].__name__
return 'Exception'
def subject_suffix():
if request:
return '{} at {}'.format(
exception_name(),
request.path_info
)
return exception_name()
def subject():
return '{}{}'.format(
subject_prefix,
subject_suffix()
)
mail.mail_admins(
subject=subject(),
message=reporter.get_traceback_text(),
fail_silently=True,
html_message=reporter.get_traceback_html()
)