Djangoの本番環境でTracebackのログを記録する

Djangoの本番環境でTracebackのログを記録する

ユーザー「ログインしようとすると500エラーでます」
私「log確認して対応します」
私(あれ、Djangoってデフォルトだとtracebackの記録残してくれてないの!?)
私(現象再現しないし困った。。。)
となったので慌ててエラーのログを残すように対応しました。
pythonの標準機能のloggingによる出力の解説はたくさんありますが、今回は「sentry」というwebサービスを使ってログを残す方法をまとめます。

sentryの登録

sentryの公式サイトはこちらです。

右上の「GET STARTED」を選択し、フォームを記入するかGoogleアカウントなどのソーシャルアカウントでログインをしてサインアップしてください。基本的に案内通りに進めていけば迷うことはないかと思います。プラットフォームを選択するところではDjangoを検索して選択してください。すると、

import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

sentry_sdk.init(
dsn="https://xxxxxxxxxxxxxxxxxxxx999999999999999@sentry.io/9999999",
integrations=[DjangoIntegration()],

# If you wish to associate users to errors (assuming you are using
# django.contrib.auth) you may enable sending PII data.
send_default_pii=True
)

このようなコードをsetting.pyに貼るように言われます。このDSNはユーザー固有の値になっています。このコードをコピーし忘れてしまった場合はSettings>Projects>自分のプロジェクト名>Client Keys(DNS)とたどれば確認することができます。

sentry-sdkのインストールと実装

Djangoプロジェクトにコードを追記して行く前にsentry-sdkをインストールしましょう。

pip install sentry-sdk

Anaconda/minicondaの方は

conda install sentry-sdk

でインストールできます。インストールができたら先ほどのコードをsetting.pyにコピペします。これで設定完了です。簡単すぎます。

正しく動作するかを確認するために、最上位のurl.pyに下記を追記します。

from django.urls import path  #追記しなくてもきっとすでにimportしていると思います。

def trigger_error(request):
division_by_zero = 1 / 0

urlpatterns = [
...いろんなpath....
path('sentry-debug/', trigger_error),    #これを追記
]

普段はview.pyの中の関数を呼び出しているかと思いますが、url.pyに直接関数を書いても正しく動作します。追加したtrigger_error関数は見ての通り「0割り」を行うものなので、当然エラーが出ます。エラーが発生した時にsentryにlogが残れば設定がうまくいっていると言うことになります。

動作確認

それではうまく行くか確認してみましょう。

python manage.py runserver

いつも通りテスト環境を立ち上げ、http://127.0.0.1:8000/sentry-debugにアクセスします。setting.pyでDEBUG=Trueとしていれば、次の画像のようなエラーが出るかと思います。

一方sentryの方を確認してみると

このようにZeroDivisionErrorを検知してlogが残っています。うまく設定できていることが確認できました。IssueをクリックするとTracebackやHTTP通信の情報、クライアントの情報などをみることができます。

最後にurl.pyに追加したdebug用の関数とurlpatternを削除して終了です。