プロンプトとコンテキスト
マルチテナントAPIのレイテンシヒストグラムが、トラフィックのピーク時にp99の悪化を示しています。user_id、完全なURL、またはリクエストパラメータをメトリクスラベルとして追加すると、時系列データとコストが際限なく増大してしまいます。集約されたバケットを確認するだけでは、単一の低速リクエストを特定することはできません。調査担当者がチャートからトレースへ、さらにログや依存関係へとたどれるように、メトリクスサンプルに少数のトレース参照を付与するメトリクスエグザンプラを設計してください。
この質問では、メトリクスの集約セマンティクスと外部エグザンプラ参照を適切に分離できているかが問われます。OpenTelemetryでは、エグザンプラをメトリクスイベントに関連付けられた記録値として定義しており、trace_id、span_id、観測時刻、およびフィルタリングされた属性を保持できます。同様にOpenMetricsでも、値、ラベルセット、およびタイムスタンプが必要です。プライマリメトリクスは低カーディナリティを維持しなければならず、エグザンプラは隠れたラベルシステムではありません。
面接官が評価するポイント
- エグザンプラがヒストグラムのバケット、count、sumを変更せず、集約の外側にある観測値を参照するものであると理解しているか。
- トレースベースまたは確率的サンプリングを選択し、レート、テールレイテンシのカバレッジ、およびコスト間のトレードオフを説明できるか。
- リクエスト全体、トークン、または個人データをメトリクスに含めることなく、
trace_idやspan_idなどの安定した参照を使用しているか。 - 単にリンクを描くだけでなく、タイムスタンプ、順序の不一致、バックエンドでのドロップ、保持期間、およびマルチテナント認可を処理できるか。
- 低カーディナリティメトリクスを使用して時間枠を特定し、エグザンプラを使用して代表的なトレースを検証した上で、ログ、依存関係、ビルドバージョンを追跡できるか。
最初に確認すべき明確化のための質問
- どのメトリクスバックエンド、トレースバックエンド、可視化ツールが使用されており、それらはエグザンプラクエリとディープリンクをサポートしているか?
- どのインストゥルメントが対象か(Histogram、Counter、またはGauge)?p99はサービス側とゲートウェイ側のどちらで測定されているか?
- サンプリングはすべてのエラー、テールレイテンシ、またはテナントおよびバージョンごとのバジェットを対象とすべきか?リージョン間で統一されたポリシーはあるか?
- 参照を制約する保持期間、アクセス制御、マスキング(redaction)、テナント分離のルールは何か?
- どのようなメモリ、ネットワーク、ストレージのバジェットが適用され、エグザンプラがドロップされた場合でもプライマリメトリクスは利用可能であり続ける必要があるか?
30秒での回答例
「低カーディナリティのレイテンシヒストグラムを維持し、サンプリングされた少数のセットに対してのみtrace_id、span_id、観測値、およびタイムスタンプを付与します。サンプリングではエラーとテールレイテンシを優先し、ユーザー識別子はメトリクスラベルから除外します。メトリクスバックエンドは短期間の参照を保存し、トレースのディープリンク遷移の前に権限チェックを実行します。バケットの統計が変化していないこと、時間枠がエグザンプラを返すこと、ドロップが発生してもプライマリメトリクスに影響しないことを検証します。ヒット率、リンク成功率、メモリオーバーヘッド、機密フィールドのスキャンに基づいて品質ゲートを設定します。」
ステップバイステップの解決策
ステップ 1: メトリクスとエグザンプラの境界を設定する
ヒストグラムのラベルは、service、route_template、region、status_classなどの限定されたディメンションに制限します。観測値は依然としてbucket_counts、count、sumに寄与しますが、エグザンプラは1つの追跡可能な参照を保存するのみであり、トレースごとに新しい時系列を作成してはなりません。
ステップ 2: テールカバレッジのためのサンプリング
リクエストコンテキスト内でトレースサンプリングを決定し、サンプリング対象となりエラー、レイテンシしきい値、またはディメンションごとのバジェットに一致した際に、観測値を該当するHistogramサンプルに関連付けます。リザーバー(reservoir)やリングバッファなど、サービスおよびメトリクスごとに固定容量を使用します。ヒット数がトラフィック量と誤認されないように、サンプリングの変更にはバージョン管理を行います。
ステップ 3: 参照と時間のエンコード
エグザンプラには、数値、ラベルセット、観測時刻が含まれます。トレース参照にはtrace_idとspan_idを使用する必要があります。タイムスタンプは観測時刻に近く、メトリクスのサンプルウィンドウと一致している必要があります。レシーバーがラベルを切り詰めたりエグザンプラを破棄したりする可能性があるため、クエリパスは『メトリクスは存在するがエグザンプラは存在しない』ケースをサポートする必要があります。
latency_seconds_bucket{route="/checkout",le="1"} 982
# {trace_id="4f8...",span_id="91a...",build="2026.07.31"} 1.42 1753938000000ステップ 4: プライバシー、カーディナリティ、コストを制限する
エグザンプラに未加工のURL、リクエストボディ、メールアドレス、認証トークン、またはユーザーIDを含めてはなりません。buildやリージョンなどのオプション属性には、許可リストと長さ制限が必要です。OpenTelemetryでは、Viewによってメトリクスストリームから削除された属性であっても、エグザンプラのフィルタリング済み属性としてエクスポートされる可能性があると指摘されているため、マスキングは別途設定する必要があります。1秒あたりのサンプル数、レコードあたりのバイト数、リングバッファメモリ、リモートライト、およびトレースクエリコストを見積もり、メトリクスラベルを汚染する前にエグザンプラのサンプリングレートを抑えます。
ステップ 5: クロスバックエンドジャンプの実装
ダッシュボードは選択された時間範囲のエグザンプラをクエリし、trace_idから制御されたトレースバックエンドリンクを構築します。リンクサービスはテナント、リージョン、および認可をチェックし、見つからない、期限切れ、または環境をまたぐトレースに対して明示的なステータスを返します。ログとスパンはTrace Contextを共有しますが、これら3つのシグナルが同一のストレージシステムを必要とするわけではありません。
ステップ 6: パフォーマンス低下テストとリリースの品質ゲート
固定トラフィックをリプレイし、エグザンプラを有効にする前後でバケット、count、sum、p99を比較して、集約が変わっていないことを証明します。低速リクエストやエラーリクエストを注入して、ヒット率、タイムスタンプ、トレースジャンプ、およびテナント分離を確認します。エグザンプラバックエンドを遅延、切り詰め、または無効化し、メトリクスクエリが正常に動作し続けることを確認します。品質ゲートでは、機密フィールドのスキャン、メモリ上限、リモートライトの失敗率、ジャンプの成功率、およびサービスとバージョンごとのサンプリングの公平性を網羅する必要があります。
強力な模範解答
「まず、メトリクスラベルをルートテンプレート、ステータスクラス、リージョンに限定し、ヒストグラムがp99の集約を担うようにします。リクエストにはTrace Contextを付与し、サンプリングされたトレースがエラーまたはテールレイテンシのポリシーに一致した場合、trace_id、span_id、値、およびタイムスタンプをHistogramサンプルに付与します。エグザンプラの属性は許可リストで管理し、ユーザー識別情報やリクエストボディを含めず、Viewによるエクスポート前にも再度マスキングします。」
「Prometheus/OpenMetricsのクエリは、選択したウィンドウのエグザンプラのみを返します。トレースリンクへの遷移前に権限チェックを実行し、トレースの保持期間が切れている場合は、参照期限切れの状態とともにメトリクスを引き続き表示します。負荷テストでbucket/count/sum/p99を比較し、障害訓練でバックエンドのドロップ、順序の不一致、クロステナントアクセス、バジェット枯渇などを検証します。ヒット率、最初のトレースまでの時間、メモリ、書き込みコスト、機密フィールドのスキャンによってサンプリングバジェットを決定し、高カーディナリティなラベルがメトリクスに入り込まないようにします。」
よくある間違い
trace_idをメトリクスラベルに含める → 時系列の爆発的増加を招く → エグザンプラ参照内に保持する。- 固定確率サンプリングのみを使用する → p99やエラーが長期間キャプチャされない場合がある → テール、エラー、バジェット制約付きのサンプリングを追加する。
- エグザンプラのタイムスタンプを無視する → トレースがチャートの時間枠から外れてしまう → 観測時刻を記録し、ウィンドウを検証する。
- フィルタリングされた属性が安全であると思い込む → 機密データがエグザンプラとともにエクスポートされるリスクがある → 個別の許可リスト、マスキング、認可チェックを使用する。
- エグザンプラの欠落をメトリクスの障害として扱う → 集約処理が参照データと密結合してしまう → メトリクスの可用性を維持し、エグザンプラの損失は別途監視する。
- 制限なしに参照を保持する → メモリとコストが制御不能に増大する → 固定容量、保持期間、サンプリングバジェットを設定する。
フォローアップ質問と回答
エグザンプラによってp99は変化しますか?
いいえ。その値はすでにHistogramのバケット、count、sumに含まれています。エグザンプラはコンテキストと参照を追加するだけであり、別のメトリクス系列を作成したり、観測値を二重にカウントしたりしてはなりません。
エグザンプラ属性に完全なURLを含めないのはなぜですか?
完全なURLにはユーザーデータ、トークン、および無限のカーディナリティが含まれる可能性があるためです。許可リストに登録されたルートテンプレートとバージョンを使用し、パラメータは認可およびマスキングされたトレースまたはログ側で確認します。
すべてのエグザンプラがドロップされるとどうなりますか?
メトリクスクエリとアラートは、引き続き集約時系列データを使用します。調査担当者がメトリクスからトレースへ直接ジャンプする手段は失われるため、エグザンプラの受信率とジャンプ成功率を監視します。参照パスがメトリクスの取り込みをブロックしてはなりません。
サンプリングが特定のテナントに偏っていないことをどのように証明しますか?
テナント、リージョン、バージョン、結果クラスごとにリクエスト数、サンプル数、ヒット数を比較します。最小保証枠と最大バジェットを設定し、エラーおよびテールレイテンシのヒット率を比較します。グローバルレートを引き上げるのではなく、層化サンプリング(stratified sampling)を使用してバイアスを修正します。