DjangoのDEBUGを使用せずにエラー画面や通知をする

Djangoの環境変数のDEBUGをTrueにするとエラー画面を表示させる事ができますが、DEBUGで他のロジックを条件分岐させていたり、本番環境やステージングなどでDEBUGをTRUEにしたくないことがあります。

Loggingを使った方法でエラーログを残す方法もありますが、この記事ではloggingを使わずにエラーの内容を知る方法をご紹介します。

DjangoのLoggingについては「[Python] Django ログ出力のまとめ」や「DjangoのLOGGINGの設定についてちゃんと勉強した」が参考になります。
公式ドキュメントも用意されています。

目次

環境変数のDEBUGを使わずにエラー画面を表示

djangoのデバグビュー

環境変数のDEBUGをFalseにしたままでエラー画面を出す方法をご紹介します。

開発環境と同じようにデバグビューでエラーの内容を確認したい場合はdebug.technical_500_responseを使用します。

server_error_display関数が呼び出されるとデバグビューのHTMLが返されます。

import sys
from django.http import HttpResponseServerError
from django.views import debug

def server_error_display(request):
    error_html = debug.technical_500_response(request, *sys.exc_info()).content
    return HttpResponseServerError(error_html)

500エラーが発生した時に発火するhandler500にserver_error_displayを入れると500サーバーエラーが発生した時にデバグビューを表示することができます。

...
from common.error_log import server_error_display

handler500 = server_error_display

urlpatterns = [
    path('admin/', admin.site.urls),
    ...
]

handler500以外にも

の400番系のエラーが発生した時に上書きするハンドラーも用意されています。

サーバーエラー(500エラー)が発生したら通知する

サーバーエラーが発生した時に

  • Slack
  • ハングアウト

に通知する方法をご紹介します。

どちらの通知も500エラーが起きたらrequestsを使ってpostしています。

Slackに通知する

Slackに通知するにはまずSlackのWebhookURLを取得する必要があります。
そのWebhookURLにエラー内容をPOSTして通知します。

SlackのWebhookURLの取得方法はこちらを御覧ください。
SlackのWebhookURLはhttps://hooks.slack.com/services/~のようになります。

WebhookURLが取得できたら次のコードにWebhookURLを入れてポストする準備をします。
Slackのicon_emojiは絵文字チートシートで取得することができます。

channelを省略するとIncoming WebHooksを登録するときに選択したchannelに送信されます。
channelを上書きすることで任意のchannnelに通知することができます。

import requests, json, traceback
from django.http import HttpResponseServerError

def server_error_send_to_slack(request, slack_webhook_url="https://hooks.slack.com/services/~"):
    requests.post(
        slack_webhook_url,
        data=json.dumps({
            'text': '\n'.join([
                f'Request uri: {request.build_absolute_uri()}',
                traceback.format_exc(),
            ]),
            'username': 'Django 500 error webhookbot',
            'icon_emoji': ':innocent:',
            # 'channel': '#general',
        })
    )
    return HttpResponseServerError('<h1>Server Error (500)</h1>')

500エラーが発生した時に発火するhandler500にserver_error_send_to_slackを入れて、500サーバーエラーが発生した時にSlackにpostして通知するようにします。

...
from common.error_log import server_error_send_to_slack

handler500 = server_error_send_to_slack

urlpatterns = [
    path('admin/', admin.site.urls),
    ...
]

ハングアウトに通知する

ハングアウトに通知するにはまずハングアウトのWebhookURLを取得する必要があります。
そのWebhookURLにエラー内容をPOSTして通知します。

ハングアウトのWebhookURLの取得方法はこちらを御覧ください。
ハングアウトのWebhookURLはhttps://chat.googleapis.com/v1/spaces/~のようになります。

WebhookURLが取得できたら次のコードにWebhookURLを入れてポストする準備をします。

import requests, json, traceback
from django.http import HttpResponseServerError

def server_error_send_to_hangout(request, hangout_webhook_url="https://chat.googleapis.com/v1/spaces/~"):
    requests.post(
        hangout_webhook_url,
        data=json.dumps({
            'text': '\n'.join([
                f'Request uri: {request.build_absolute_uri()}',
                traceback.format_exc(),
            ]),
        })
    )
    return HttpResponseServerError('<h1>Server Error (500)</h1>')

500エラーが発生した時に発火するhandler500にserver_error_send_to_hangoutを入れて、500サーバーエラーが発生した時にハングアウトにpostして通知するようにします。

...
from common.error_log import server_error_send_to_hangout, server_error_display

handler500 = server_error_send_to_hangout

urlpatterns = [
    path('admin/', admin.site.urls),
    ...
]

参考

Djangoで500が出たらエラー内容のログを取る。または通知。

Django Server Error (500)攻略法【2019 アドカレ】

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

目次