FastAPIにSentryを導入した話

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

個人アドベントカレンダーの2日目の記事になります。 副業で開発しているFastAPIのプロダクトにおいてエラートラッキングを行うためにSentryを導入した話です。

背景

Vue+FastAPIで構築されているシステムのバックエンド側にエラー監視ツールが導入されていなかったので、導入することになりました。

自分が参加したタイミングではすでにフロントエンド側にSentryが導入されていたので、バックエンド側のエラー監視ツールも同じSentryする方針で実装することになりました。

Sentryについては全く事前知識がなかったので、調べながらの実装になったため、今回は調べたことや実装したことをまとめて書いておこうと思います。

Sentryとは

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

エラーについてdebug,info,warn,errorの4つの種類で通知できるほか、発生した例外に関してもスタックトレースを含めて通知してくれます。

パフォーマンス監視機能は、HTTPリクエストの応答時間やデータベースのレイテンシなどを測定することができるようです。

このあたりでデモも体験できます。 https://try.sentry-demo.com/organizations/eager-cod/performance

BugsnagとSentryの違い

普段本業の方ではRuby on Railsのプロダクトにエラー監視ツールとしてBugsnagを用いているので、今回Sentryというツールがあることも知ったので、違いについて軽く調べてみました。 いくつか記事を読んでみたところ機能についてはあまり違いがないようで、導入を決めるにあたっては「Bugsnagはたくさんのサードパーティアプリとの連携が可能で、Sentryは類似のエラーを簡単に解決できることが強み」というような観点で見るということが書いてありました。

Bugsnag

  • エラーの根本原因によるグルーピング
  • JavaScript,iOS,Android,Python,RubyやJavaなどの50を超える言語やプラットフォームのサポート
  • チャットやメール、SMSなどへの即時通知

Sentry

  • リアルタイム更新機能で、ユーザーがエラーに遭遇するよりもずっと前に、スタックのあらゆる場所でコードレベルの問題を修正することができる
  • 完全なコンテキストがあるので、重要な部分を発見しやすい
  • JavaScript、Python、PHP、Ruby、Node、Java、.NET、モバイルなど、あらゆる主要なプラットフォーム、フレームワーク、言語に対応したドロップイン方式の統合

また自分はまだ触ったことがないのですが、Rollbarも同系統のツールとしてよく使われることがあるらしいです。

下記食べログさんのNext.jsでは

  • 時間単位で受信限度数が設定できる→コスト削減
  • 管理画面上でのフィルタリングが可能
  • 記事が多い

という理由でSentryを選定されていました。

実装

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

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

pipを使ってsentry_sdkをインストールします。

pip install --upgrade sentry-sdk

2. envファイルに環境変数を用意します

SentryのアカウントやProjectを立ち上げた後、「Settings」 -> 「Projects」から該当のプロジェクトを選択し、「Client Keys (DSN)」を確認してenv環境変数として設定します。

SentryのClientKeys.jpg

SENTRY_DSN=< DSNの値 >

3. FastAPIに組み込み

下記のようなinit_sentry関数を定義して、FastAPIのmain.pyから呼び出しすだけです。

import sentry_sdk
from sentry_sdk import set_user
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,
    )
# 追加分のみ抜粋
from app.sentry import init_sentry
init_sentry()

FastAPIなどのASGI Webフレームワークには SentryAsgiMiddlewareというmiddlewareが提供されているほか、SQLAlchemyのためのSqlalchemyIntegrationも用意されているので、このあたりを初期化時に組み込めば簡単に使用することができます。

今回はひとまずエラー監視ができればよさそうだったので、traces_sample_rateの値は1.0で設定しました。

この設定だけでエラーが起きたときに詳細の情報やトレースバックをSentry上で確認することができるようになりました。 スクリーンショット_2022-12-01_9_10_38.png

感想

「エラー監視ツールの導入」 と聞くと大げさに聞こえますが、想定よりもだいぶ簡単に導入することができました。 もちろんこれ以上にもパフォーマンスの計測やSlack連携、使い方に応じたカスタマイズなど、たくさんの機能が入っているようなので、完全に使いこなすためにはまだまだやることがありそうでした。

参考

いろんな事例を公開してくださっている企業や開発者の方々に感謝です。

導入について

パフォーマンス

質問・リクエストを送る

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