Sentryの「Custom Tags & Context」を極める:MTTRを劇的に縮めるためのデータ戦略
多くのエンジニアがSentryを「エラーが飛んでくる通知ツール」として使っている。それはあまりにも勿体ない。Sentryは、コードの「文脈(コンテキスト)」を蓄積し、障害という名の迷宮からエンジニアを最短距離で脱出させるための「思考の補助脳」だ。
今回は、Sentryの真価を解放する「Custom Tags」と「Context」の極限的な活用術を伝授する。
—
1. なぜ「標準のスタックトレース」だけでは足りないのか?
分散システムや複雑なマルチテナント環境において、スタックトレースは「どこで死んだか」しか教えてくれない。しかし、我々が本当に知りたいのは「どのテナントの、どの特定のビジネスフローで、どの状態のデータが引き金となって死んだのか」だ。
ここを解決するのが `setTag` と `setContext` である。
基本の使い分け(鉄則)
- Tags (インデックス対象): 検索やフィルタリング、アグリゲーションに使いたいもの。例:`tenant_id`, `feature_flag`, `region`, `version`
- Context (構造化データ): 詳細な調査用。検索はしないが、デバッグ時に必要な生の状態。例:`request_payload`, `db_snapshot`, `user_session_state`
—
2. 実践:マルチテナント環境の「神」実装パターン
フロントエンドとバックエンドが分離された環境で、特に効果を発揮する実装コード例を見てみよう。
// Sentryのスコープを適切に管理するユーティリティ
import as Sentry from “@sentry/browser”;
export const enrichSentryContext = (tenantId, userId, metadata) => {
Sentry.configureScope((scope) => {
// 1. Tags: 検索の要(Cardinalityに注意:ユニーク数が多すぎるIDはタグにするな)
scope.setTag(“tenant_id”, tenantId);
scope.setTag(“env”, process.env.NODE_ENV);
// 2. User: 標準機能は使うが、独自の識別子も混ぜる
scope.setUser({ id: userId });
// 3. Context: 構造化データの爆弾
scope.setContext(“business_flow”, {
orderId: metadata.orderId,
step: metadata.currentStep,
is_premium: metadata.isPremiumUser, // A/Bテストの切り分けにも使える
});
// 4. Breadcrumbs: エラーに至るまでの足跡を強制追加
Sentry.addBreadcrumb({
category: “payment_flow”,
message: `Initiating payment for order ${metadata.orderId}`,
level: “info”,
});
});
};
検索フィルターの極意
Sentryの検索バーで `tenant_id:12345` と打つだけで、そのテナント専用のノイズのない世界が見える。さらに `is_premium:true` と組み合わせれば、「VIPユーザーだけが遭遇しているエッジケース」を秒速で特定できる。
—
3. 生産性を爆上げする「ツール・設定」の裏技
① 開発スピードを加速させるキーボードショートカット
SentryのIssue画面でこれを使わないのは損だ。
- `j` / `k`: Issueのリストを上下移動。
- `Enter`: Issueの詳細へ。
- `Shift + r`: そのIssueを「解決済み」にする。
- `?`: 全ショートカットの表示。マウスに触れる時間を極限まで減らせ。
② チーム開発で必須の「設定共有化ルール」
`sentry.config.js` を個別に書く時代は終わった。チーム全体で型を強制するために、共通のラッパーライブラリを作るべきだ。
ベストプラクティス構成例 (`sentry-init.ts`)
// インターフェースを定義し、タグの揺らぎを防ぐ
interface SentryMetadata {
tenantId: string;
featureKey: string;
}
export const captureExceptionWithContext = (err: Error, meta: SentryMetadata) => {
Sentry.withScope((scope) => {
scope.setTag(“feature”, meta.featureKey);
scope.setTag(“tenant”, meta.tenantId);
Sentry.captureException(err);
});
};
これにより、「タグ名が `tenant` なのか `tenant_id` なのか」という無益な論争をコードベースで解消する。
③ 絶対に入れるべき神プラグイン
- Sentry GitHub App: Pull Requestにエラーが紐付くと、コード修正時に「どのコミットがこのエラーを直したか」が自動追跡される。
- Sentry Slack Integration: 通知の「絞り込み(Alert Rules)」を徹底せよ。「深夜に通知が鳴っていいのは、特定の重要プロジェクトのエラーのみ」に絞るのが、エンジニアのメンタルヘルスを守る唯一の道だ。
—
4. 最後に:プロとしての心構え
監視は「守り」ではない。「攻め」のエンジニアリングだ。
エラーログをただ眺めるな。「このエラーが次に発生する時、調査をゼロにするためには何というタグが必要か?」を常に自問自答せよ。
Sentryに埋め込んだタグは、数ヶ月後の自分への最高のプレゼントになる。今日から、ログに「物語」を語らせろ。それが、真のオブザーバビリティだ。