Sentryの「Span Operations」をハックせよ:GraphQLのN+1地獄を完封するオブザーバビリティの神髄
「またGraphQLのレスポンスが遅い? でもどこでコケてるかわからない」
そんな霧の中を彷徨うようなデバッグは今日で終わりにしよう。
Sentryは単なる「エラーログ集積所」ではない。正しく設定すれば、「どこで、なぜ、何が」遅延しているかを、フロントエンドからDBのクエリまで一本の線(トレース)で繋ぐ最強の観測兵器に変貌する。
今回は、特にGraphQL環境で猛威を振るう「N+1問題」をSentryの`Span Operations`で可視化し、根絶するための「現場のプロしか知らない」裏技を伝授する。
—
1. なぜ「Span Operations」が最強の武器なのか
GraphQLは「1つのリクエストで複数のリゾルバが走る」という特性上、従来のメトリクス監視では内訳が隠蔽されがちだ。ここで活躍するのがSpan Operationsだ。
Sentryのトレースデータにおいて、`op`(Operation)タグを適切に分類することで、「どのリゾルバが、何回呼ばれ、何ミリ秒溶かしたか」をSentryのダッシュボード上でフィルタリング可能にする。
現場で絶対に入れるべき「カスタム・スパン」の作法
デフォルトの計装だけでは足りない。重要なクエリ処理には必ず手動でSpanを刻め。
// GraphQLリゾルバでの実践例
const resolvers = {
Query: {
users: async (_, __, { dataSources }, info) => {
// Sentryのスパンを開始(計測の解像度を上げる)
return Sentry.startSpan({ name: ‘resolve-users’, op: ‘db.query.users’ }, async (span) => {
const users = await dataSources.db.getUsers();
// Spanにメタデータを付与して検索しやすくする
span.setAttribute(‘graphql.field’, ‘users’);
return users;
});
}
}
};
ここがプロのポイント:
`op`には `db.query` や `cache.get` など命名規則(プレフィックス)を強制しろ。これにより、Sentryのパフォーマンス画面で「DBの負荷が高いのか、外部APIが詰まっているのか」を一瞬でソートできるようになる。
—
2. N+1問題を可視化する「隠れた」設定
N+1問題の正体は、同じ `op` が短時間に異常な回数繰り返されることだ。Sentryの「Performance」画面で、特定のトランザクションを開き、Waterfallグラフを眺めるのが基本だが、実はここから一歩進んだ見方がある。
「Group by Operation」でボトルネックを特定する
1. Sentryの「Performance」->「Transactions」を開く。
2. GraphQLのクエリを選択。
3. 「Span Summary」タブを開く。
4. ここで `op` を基準にソートすると、「最も実行回数が多い(Count)」「最も時間を食っている(Self Time)」スパンがトップに躍り出る。
「1つのリクエストで同じDBクエリが50回も走っている」という事実は、ここで初めて冷徹な数字として突きつけられる。
—
3. チーム開発を加速させる「設定共有」ベストプラクティス
属人化を防ぎ、全員が同じ解像度でデバッグできるようにするために、`sentry.config.js` を以下のように標準化せよ。
{
“dsn”: “…”,
“tracesSampleRate”: 0.2, // 本番は0.2〜0.5で十分。エラー時は別設定へ
“integrations”: [
“Sentry.browserTracingIntegration()”,
“Sentry.graphqlIntegration()” // GraphQL専用の計装プラグインは必須
],
// 重要なヘッダーやユーザーIDをタグとして伝搬させる
“tracePropagationTargets”: [“localhost”, /^https:\/\/api\.yourdomain\.com/]
}
プロのTips:
- 神プラグイン: `Sentry.graphqlIntegration()` は必ず入れろ。これでリゾルバの階層構造が自動的にトレースツリーにマッピングされる。
- キーボードショートカット: Sentry画面で `Cmd + K` (Ctrl + K) を叩け。プロジェクト名やIssue IDを検索する際に、マウスを使うのは時間の無駄だ。
—
4. 現場で震えるほど役立つ「予兆検知」ルール
Sentryの「Alerts」設定で、エラーが出るまで待つな。「パフォーマンス低下」をアラートにしろ。
- 設定値: `transaction.duration` が p95 で 1000ms を超えたら Slack に通知。
- 合わせ技: これに加えて `span.op:db.query` の実行回数が 1 リクエストあたり 20 回を超えたら「N+1の疑いあり」として警告を出す。
これを設定するだけで、QAチームがバグ報告を上げる前に、エンジニアが「あ、N+1踏んでるわ」と修正する文化が生まれる。
—
まとめ:オブザーバビリティとは「問いを立てる力」
Sentryの真の価値は、エラーを眺めることではなく、「なぜこのリクエストは遅いのか?」という問いに対して、データに基づいた答えを即座に引き出せることにある。
1. `op` タグを統一し、グラフのノイズを消せ。
2. Span Summaryで「Count」と「Self Time」を毎日チェックしろ。
3. アラートは「エラー」ではなく「パフォーマンスの劣化」に設定しろ。
明日から君たちのチームのダッシュボードは、ただのログ置場ではなく、「システムの挙動が見える化された聖域」に変わるはずだ。さあ、今すぐSpanを刻みに行こう。