私の Django アプリがデバッグ情報をメールではなく slack に送信するようにしたいと考えていました。これはデフォルトです。
- メールを無効にするのは簡単です。
ADMINS
設定にメールを入れないでください - Slack への情報送信は簡単です。着信 Webhook を追加するだけです
では、メッセージを送信するロジックはどこに作成すればよいでしょうか。ミドルウェアはかなり良いアイデアのようです。私は次のようなことをします
class ExceptionMiddleware:
def process_exception(self, request, exception):
pretty_debugging_message = ...
requests.post("https://my-slack-url/", {...})
None
ミドルウェアは、システムの残りの部分に干渉しないように戻るだけです。何しろ、メール送信はすでに無効になっています。
だから私の質問は: django が収集するすべてのデバッグ情報を取得するにはどうすればよいですか? 私は次のようなことができます
import sys, traceback
pretty_debugging_message = '\n'.join(
traceback.format_exception(*sys.exc_info())
)
ただし、これはトレースバックのみを提供します。すべてのローカル、セッション、クライアント IP などはどうですか?
https://docs.djangoproject.com/en/1.8/howto/error-reporting/を読むと、ミドルウェアが処理されるまで、つまりすべてが試行されるまで、そのすべての情報が収集されないことがわかります。エラーが処理されていない場合、Django はその ErrorReporter を実行し、情報をログに記録します。どうにかしてそのプロセスに介入し、情報を slack に送信させることはできますか? そのほうがいいでしょうか?
アップデート
私の解決策:
class SlackHandler(AdminEmailHandler):
def emit(self, record):
try:
request = record.request
subject = '%s (%s IP): %s' % (
record.levelname,
('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
else 'EXTERNAL'),
record.getMessage()
)
filter = get_exception_reporter_filter(request)
request_repr = '\n{0}'.format(filter.get_request_repr(request))
except Exception:
subject = '%s: %s' % (
record.levelname,
record.getMessage()
)
request = None
request_repr = "unavailable"
subject = self.format_subject(subject)
if record.exc_info:
exc_info = record.exc_info
else:
exc_info = (None, record.getMessage(), None)
message = "%s\n\nRequest repr(): %s" % (self.format(record), request_repr)
reporter = ExceptionReporter(request, is_email=True, *exc_info)
html_message = reporter.get_traceback_html() if self.include_html else None
requests.post(settings.SLACK_WEBHOOK_URL, json={
"fallback": message,
"pretext": "An error occured",
"color": "#ef2a2a",
"fields": [
{
"title": "Error",
"value": message,
"short": False
}
]
})
settings.py で:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'slack': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'myapp.myapp.SlackHandler'
}
# 'mail_admins': {
# 'level': 'ERROR',
# 'filters': ['require_debug_false'],
# 'class': 'django.utils.log.AdminEmailHandler'
# }
},
'loggers': {
'django.request': {
'handlers': ['slack'],
'level': 'ERROR',
'propagate': True,
},
}
}