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をコピーしました!

エンジニアを目指す方必見!おすすめプログラミングスクール

最短でエンジニアになるには、いかに効率よく学習するかが重要です。モチベーションを維持しながら最短でエンジニアを目指すならプログラミングスクールを利用するのもおすすめです。

目次
閉じる