FastAPI に Sentry を導入する方法(sentry-sdk[fastapi] 対応)

8分で読めるテック
最終更新:

副業で開発に参加していた FastAPI プロダクトに、Sentry を使ったエラートラッキングを導入した記録です。「エラー監視ツールの導入」と聞くと大掛かりに感じますが、実際に手を動かしてみると数十行の設定で完了しました。同じ構成で試そうとしている方に届けばと思い、手順とコードをまとめます。

背景

Vue + FastAPI で構築された取引先のシステムで、バックエンド側にエラー監視が入っていませんでした。フロントエンドにはすでに Sentry が導入されていたため、バックエンドも同じ Sentry に揃える方針になりました。

自分は Sentry について事前知識がほぼゼロの状態から調べながら実装したので、この記事はそのときに把握した内容を整理したものです。

Sentry とは

Sentry はソフトウェアのエラー追跡とパフォーマンス監視のためのオープンソースツールです。

エラーは debug・info・warning・error の 4 段階で通知でき、例外が発生した場合はスタックトレースも一緒に送信されます。パフォーマンス監視機能では HTTP リクエストの応答時間やデータベースのレイテンシを計測できます。

Bugsnag・Rollbar との違い

本業では Ruby on Rails のプロダクトで Bugsnag を使っていたので、Sentry と何が違うのかも調べました。

機能面の差は大きくなく、選定の観点としては次のような整理が参考になりました。

  • Bugsnag: サードパーティアプリとの連携が豊富。エラーを根本原因でグルーピングする機能が強み
  • Sentry: 類似エラーの解決ワークフローが整理されている。コードレベルの問題を特定しやすい UI

食べログさんのフロントエンドブログでは、Sentry を選んだ理由として「時間単位の受信制限でコスト管理できる」「管理画面のフィルタリングが使いやすい」「参考記事が多い」が挙げられていました。

Rollbar も同系統のツールとして比較対象になりますが、今回は既存のフロントエンド側に合わせて Sentry を選びました。

FastAPI への導入手順

公式ドキュメントの Python ガイドを参考にして実装しました。

1. sentry-sdk のインストール

FastAPI(Starlette ベース)向けの extra を含めてインストールします。

pip install --upgrade "sentry-sdk[fastapi]"

[fastapi] extra を指定すると StarletteIntegrationFastApiIntegration が同梱されます。SQLAlchemy を使っている場合は [fastapi,sqlalchemy] としてもよいです。

2. 環境変数に DSN を設定

Sentry のプロジェクトページで「Settings → Client Keys (DSN)」から DSN を取得し、環境変数に設定します。

SentryのClientKeys

SENTRY_DSN=<DSN の値>

3. 初期化関数を作成

sentry.py を作成して init_sentry() 関数にまとめます。SENTRY_DSN が未設定のとき(ローカル開発など)は何もしない設計にしておくと、環境ごとの切り替えが楽です。

# sentry.py
import sentry_sdk
from sentry_sdk.integrations.fastapi import FastApiIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.starlette import StarletteIntegration

from app.core.config import settings


def init_sentry() -> None:
    if settings.SENTRY_DSN is None:
        return

    sentry_sdk.init(
        dsn=settings.SENTRY_DSN,
        environment=settings.ENV,
        integrations=[
            StarletteIntegration(),
            FastApiIntegration(),
            SqlalchemyIntegration(),
        ],
        traces_sample_rate=1.0,
    )

StarletteIntegrationFastApiIntegration はセットで指定する必要があります。FastAPI は Starlette をベースにしているため、両方を渡すことでリクエスト情報が正しくキャプチャされます。

traces_sample_rate=1.0 はすべてのトランザクションをトレースする設定です。トラフィックが多い環境では 0.1(10%サンプリング)などに下げてコストを調整します。

4. main.py から呼び出す

# main.py(追加分のみ)
from app.sentry import init_sentry

init_sentry()

アプリ起動時に一度呼び出すだけです。これでエラーが発生したときにスタックトレースと詳細情報が Sentry に送信されるようになります。

Sentry でエラーが表示されている様子

やってみた感想

設定量は思ったより少なく、sentry_sdk.init() の呼び出しとインテグレーション指定がほぼすべてでした。ASGI フレームワーク向けに StarletteIntegration が用意されているおかげで、自分でミドルウェアを書く必要がありません。

パフォーマンス計測・Slack 通知・サンプリングレートの細かい調整など、今回は使わなかった機能がまだ多いので、規模が大きくなったタイミングで追って設定を見直す予定です。

参考

質問・リクエストを送る

記事についての質問や、取り上げてほしいテーマがあればお気軽にどうぞ。いただいた質問はブログ記事として回答し、Q&Aページで公開することがあります。

このサイトについて

井上 周(Amane Inoue)の個人ブログです。技術・読書・ドラマ・旅・大学生活のことを書いています。