背景とSentry Self-hostedを選んだ理由
以前、私の監視システムは15台のサーバーを監視するために、完全にPrometheusとGrafanaに依存していました。この構成はインフラの障害通知には非常に効果的でした。しかし、NullPointerExceptionやKeyErrorといったエラーが発生した際, Prometheusはコード内部まで踏み込むことができないため、全く太刀打ちできませんでした。以前は、各サーバーにSSHでログインし、Graylog上の数GBものログを漁って手がかりを探していました。このプロセスは非常に気が滅入るもので、時間も浪費していました。
Sentry Self-hostedを導入して6ヶ月が経過し、チームのデバッグフローは180度変わりました。単に抽象的なエラーを報告するのではなく、Sentryは詳細なスタックトレース、環境変数、さらにはユーザーのブラウザ情報まで提供してくれます。Cloud(SaaS)版ではなくSelf-hosted版を選んだ理由は主に2つあります。イベント数が増えた際のコストを月額約26ドル(Teamプラン)節約できること、そしてユーザーデータが社内インフラの外に出ないことを保証するためです。
システム要件:この「モンスター」を侮ってはいけない
Sentryは実のところ、PostgreSQL、Redis、ClickHouse、Kafka、そして大量のWorkerで構成される複雑なエコシステムです。もし1GBや2GBのRAMを搭載したVPSで動かそうとしているなら、率直に言って「最初から諦める」ことをお勧めします。
- CPU: 最低4コア(KafkaとClickHouseのストリーム処理のため)。
- RAM: 最低8GB(長期的にスムーズに動作させるには16GBを推奨)。
- Disk: 20GB以上の空き容量。ClickHouseのログ書き込み速度が非常に速いため、SSDを推奨。
- OS: Ubuntu 22.04 LTS または最新のDockerをサポートするディストリビューション。
クイックインストール手順
Sentryは、手動設定の負担を軽減するための自動インストールスクリプトを提供しています。公式リポジトリから直接クローンして進めます。
1. インストーラーのダウンロード
cd /opt
sudo git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
2. セットアップスクリプトの実行
GitHubのReleaseページを確認し、安定版をチェックアウトすることをお勧めします。そうしない場合、スクリプトは自動的にmasterブランチの最新版を取得します。
sudo ./install.sh
このプロセスは、ネットワーク速度にもよりますが約15分かかります。スクリプトが数十のDockerイメージをプルし、データベースを構築します。画面に管理者アカウントの作成を求めるプロンプトが表示されたら、Yを選択してログイン情報を入力してください。
3. システムの起動
スクリプトが完了したら、コンテナを起動させます:
docker-compose up -d
これで、Sentryの管理画面がhttp://IP_SERVER:9000で利用可能になります。
本番環境で安定稼働させるためのチューニング
Sentryを真に効率的に機能させるには、デフォルト設定のままにすべきではありません。以下は、私が導入時に必ず調整する2つのポイントです。
メール設定(SMTP)
メール設定がないと、Sentryはアラート送信やパスワードリセットができず、「目と耳を塞がれた」状態になります。sentry/config.ymlファイルを開き、SMTPのパラメータを入力してください:
mail.backend: 'smtp'
mail.host: 'smtp.gmail.com'
mail.port: 587
mail.username: '[email protected]'
mail.password: 'your-app-password'
mail.use-tls: true
ディスク容量不足の防止
イベントデータは非常に速いスピードで蓄積されます。制御しないと、数週間でディスクが真っ赤(満杯)になります。私は通常、.envファイルのSENTRY_EVENT_RETENTION_DAYS変数を30日に設定しています。この数字は、ストレージに負荷をかけすぎずにエラーを追跡するのに十分な期間です。
アプリケーションとSentryの連携
サーバーが稼働したら、コードへの統合は数分で完了します。最も一般的な2つのスタックの例を以下に示します。
Python (Flask/FastAPI) の場合
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
sentry_sdk.init(
dsn="http://[email protected]/1",
integrations=[FlaskIntegration()],
traces_sample_rate=0.1, # リソース節約のため10%のみサンプリング
)
フロントエンド (React/Vue) の場合
クライアント側のエラー監視は、最も価値のある機能です。ユーザーが遭遇しても報告されることのないJavaScriptエラーを可視化できます。
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: "http://[email protected]/1",
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 0.1,
});
6ヶ月間の運用を経て得られた教訓
Issue Grouping機能は、まさに救世主です。1,000人のユーザーが同じエラーに遭遇した際、Sentryは1,000通の迷惑メールで受信トレイを爆撃する代わりに、それらを1つの項目にまとめてくれます。これにより、チームは最も影響の大きいエラーに集中できるようになります。
いくつかの「血の滲むような」経験則:
- 100%のサンプリングレートは避ける:トラフィックの多いアプリでは、すべてのリクエストでトレースを送信するとネットワークが詰まります。10%(0.1)から始めて、徐々に調整しましょう。
- 常にSource Mapsをアップロードする:Source Mapsがないと、フロントエンドのエラーは意味不明な難読化(minified)されたコードの羅列になってしまいます。CI/CDパイプラインにアップロード手順を組み込みましょう。
- DSNを保護する:悪意のあるユーザーによってサーバーにゴミデータがスパム送信されるのを防ぐため、DSNを公開リポジトリにコミットしないでください。
Sentryのセルフホストは最初は手間がかかるように見えますが、それによって得られる価値は計り知れません。私たちのチームのMTTR(平均修復時間)は数時間から数分に短縮されました。無機質なログから推測するのではなく、エラーが発生した瞬間にその場所を正確に把握できるようになったのです。
