ご覧いただきありがとうございます!
領護(りょうご)です。
Djangoを本番環境で運用していると、エラーが発生していないか気になりますよね?
今回は、Djangoの500エラーをSlackに通知し、トレースバックの内容まで確認する方法を解説します。
上記のように、Slackにエラー内容を通知し、トレースバックも確認できます。
実行環境
Docker Desktop:4.37.0
Python:3.12.8
Django:5.1.3
requests:2.31.0
SlackのWebhook URLを取得する
Slackに通知を送るには、Webhook URLが必要です。
Webhook URLとは、特定のサービスやアプリケーションが他のサービスと通信する時に使用するURLです。
主に、イベントが発生した際に自動で通知を送信したり、データを送るために使用します。
以下の手順で取得します。
1.https://samurai-world.slack.com/intl/ja-jp/appsを開き、右上の「サインイン」をクリック
2.各Slackのアカウントにサインイン
※ Slackのアカウントをお持ちでない場合は、アカウント作成を行ってください。
3.サインイン完了後、右上の「管理」をクリック
※ ページリンクが「https://ワークスペース名.slack.com/marketplace」になっていることを確認してください。
4.右上の検索窓に「incoming webhooks」と入力して検索
5.検索結果の中から「incoming Webhook」をクリック
6.「Slackに追加」をクリック
7.通知を送りたいチャンネルを選択
注意!
チャンネルを作成していない場合は、選択ができないので、先に通知用のチャンネルを作成しておいてください。
8.チャンネル選択後、「Incoming Webhook インテグレーションの追加」をクリック
9.Webhook URLの項目にある「URLをコピーする」をクリック
次のプログラム作成に使うのでどこかに控えておいてください。
10.説明ラベル、名前、アイコンのカスタマイズができるので自分好みに設定する
※ 初期設定でも大丈夫です。
11.設定完了後、「設定を保存する」をクリック
これでWebhook URLの新規作成と取得が完了しました。
続いてプログラムの作成に移ります。
フォルダ構成
sample_web/
├── .env # 環境変数ファイル
├── docker-compose.yml # Docker Compose設定ファイル
├── manage.py # Django管理スクリプト
├── sample_project/ # プロジェクト名
│ ├── asgi.py # ASGI設定ファイル
│ ├── settings.py # プロジェクト設定ファイル
│ ├── urls.py # URLルーティング
│ ├── wsgi.py # WSGI設定ファイル
│ ├── static/ # 静的ファイルディレクトリ
│ │ └── css/
│ │ └── base.css # ベースCSSファイル
│ └── templates/ # HTMLテンプレートディレクトリ
│ └── home.html # ホームページのテンプレート
├── home/ # アプリフォルダ
│ ├── views.py # ビューファイル
│ └── migrations/ # マイグレーションファイル
└── common/ # 共通機能用フォルダ
└── send_error_log.py # エラーログ送信スクリプト
今回、解説するフォルダ構成は、上記の構成になります。
解説に使用するのは、common/send_error_log.py、home/views.py、sample_project/urls.py、sample_project/settings.pyの4つを使用します。
必要なライブラリのインストール
pip install requests
通知を送信する時に必要なライブラリ「requests」をインストールします。
※ 既にインストールしている方は、スキップしてください。
Slackにエラーを通知するプログラムを作成
Slackにエラーを通知する処理をcommon/send_error_log.pyに作成します。
import traceback
import requests
import json
from django.views.decorators.csrf import requires_csrf_token
from django.views.defaults import server_error
# Slackにメッセージを送信する
def send_error_to_slack(message_list, color, username):
WEBHOOK_URL = "ここに先ほどコピーしたWebhook URLを張り付け"
# メッセージを送信
requests.post(
WEBHOOK_URL,
data=json.dumps(
{
"attachments": [
{
"text": "\n".join(message_list),
"color": color,
}
],
"username": username,
}
),
)
# 500番エラーをSlackに通知
@requires_csrf_token
def server_error_send_to_slack(
request,
template_name="500.html",
):
# Slackにエラーメッセージを通知する
message_list = [
"🚨 **500 Internal Server Error 発生** 🚨",
f"URL: {request.build_absolute_uri()}",
f"メソッド: {request.method}",
f"Traceback:```\n{traceback.format_exc()}\n```",
]
# Slackにエラーメッセージを通知する
send_error_to_slack(message_list, "danger", "システムエラー通知")
return server_error(request, template_name)
Slackにエラーを送信する処理全体のプログラムです。
send_error_to_slack関数は、メッセージを送信する基本設定になります。
server_error_send_to_slack関数は、送信するメッセージの内容を設定しています。
WEBHOOK_URL = "ここに先ほどコピーしたWebhook URLを張り付け"
ここには、先ほどコピーしたWebhook URLを張り付けてください。
注意!
解説を簡単にするために、今回はWebhook URLをコードに直接書いていますが、実際には環境変数にして読み込むことをおすすめします!
WEBHOOK_URL = "https://hooks.slack.com/services/~~~"
張り付けると上記のようになります。
# Slackにエラーメッセージを通知する
message_list = [
"🚨 **500 Internal Server Error 発生** 🚨",
f"URL: {request.build_absolute_uri()}",
f"メソッド: {request.method}",
f"Traceback:```\n{traceback.format_exc()}\n```",
]
今回通知するメッセージ内容は、下記のようにしています。
ここは通知したい内容を自由に変更してもOKです!
通知メッセージ内容
URL:エラーが発生したページリンク
メソッド:GET / POSTのどちらでエラーが発生したか
Traceback:エラーの詳細を表示するトレースバックを表示
500エラーのトリガー設定
500エラーが発生した時に処理が実行するようにトリガーをsample_project/urls.pyに設定します。
from django.contrib import admin
from django.urls import include, path
from common.send_error_log import server_error_send_to_slack
urlpatterns = [
path("admin/", admin.site.urls),
# ~~~
]
# 500番エラーをSlackに通知する設定
handler500 = server_error_send_to_slack
500エラーが発生した際にSlackへ通知を送るため、先ほど作成した関数をインポートし、handler500に設定します。
これで、エラー発生時に自動で通知が届くようになります!
500エラーが届くかテストする
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
500エラーが届くかテストするには、sample_project/settings.pyのDEBUGをFalseに設定を変更してください。
from django.views.generic import TemplateView
# ホームページ
class HomePage(TemplateView):
template_name = "home.html"
def get(self, request, *args, **kwargs):
# 500エラーを起こす
print(hogehoge)
return super().get(request, *args, **kwargs)
home/views.pyに定義していない「hogehoge」変数をprintするように500エラーをわざと起こしてみます。
そうするとSlackにエラーが通知されます!
トレースバックもきっちり表示されています。
簡単ですね!
おまけ:特定の処理を監視する方法
今回は、500エラーのSlackに通知する方法を解説しましたが、実は特定の処理にもエラー通知を送ることができます。
from django.views.generic import TemplateView
from common.send_error_log import send_error_to_slack
# ホームページ
class HomePage(TemplateView):
template_name = "home.html"
def get(self, request, *args, **kwargs):
try:
# 感知させたい処理を行う
pass
except Exception:
# 処理が上手くいかない時にエラーメッセージを設定して通知
message_list = [
"🚨 **500 Internal Server Error 発生** 🚨",
f"〇〇の処理でエラーが起きちゃった!テヘペロ!",
]
send_error_to_slack(message_list, "danger", "システムエラー通知")
return super().get(request, *args, **kwargs)
例えば、home/views.pyに例外処理を追加することで、エラーを感知した際に独自のエラーメッセージを作成し、Slackに通知することが可能です。
実際のエラー通知になります。
重要な処理を監視したい場合に便利ですね!
最後に
Djangoの500エラーをSlackに通知し、トレースバックを表示する方法を解説しました。
本番環境の監視や運用の効率化にぜひ活用してください!