investigating-metric-anomalies について
メトリクスの変化をログやトレースと結び付けて異常を調べるスキルです。異常の発生時刻と影響を受けたラベルから、対象を絞ったクエリを行い、証拠に基づいて原因候補を導きます。
主な機能
- 01異常の規模と発生時刻を分析
- 02変化が大きいラベルを特定
- 03フィルターと式を使ったメトリクス検索
- 04メトリクスとログ、トレースの関連付け
- 05原因、影響範囲、確度の要約
活用シーン
- 01増加する取り込み遅延の調査
- 02サービス停止と処理遅延の切り分け
- 03遅延やエラーの変化を招いたサービスや依存先の特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill investigating-metric-anomaliesインストール後、Claude Code で/investigating-metric-anomaliesを入力して読み込まれたか確認します。
詳細
メトリクスの異常を調査する
目的は、「取り込みの遅延が増加している」というメトリクス上の症状から、根拠を示して原因をすばやく絞り込むことです。メトリクスから分かるのは「何が」「いつ」起きたかであり、ログとトレースから分かるのは「なぜ」起きたかです。以下の手順に従ってください。まず、コストが低く情報量の多い呼び出しを行い、影響範囲が不明な場合にのみ調査対象を広げます。
手順
1. メトリクスを特定する
正確なメトリクス名が分かっている場合は、次の手順に進んでください。分からない場合は、症状を表す部分文字列(lag、error、latency、queue)を指定して metric-names-list を呼び出します。返された metric_type によって、確認する観点が決まります。カウンター(sum)は rate/increase としてのみ意味があり、ゲージは avg、ヒストグラムは histogram_quantile を使います。
2. まず特徴を把握する — 1回の呼び出しで3つの答えを得る
メトリクス名と anomalyFrom(アラートの発火時刻、またはユーザーが異常に気づき始めた時刻)を指定して characterize-metric-anomaly を呼び出します。時刻に確信がない場合は、少し余裕を持たせて指定します。デフォルトでは直前のウィンドウと比較し、次の情報が返されます。
- どの程度深刻か:
direction、change_ratio、anomaly_peakとbaseline_meanの比較。directionがflatの場合、ウィンドウかメトリクスが適切ではありません。ウィンドウを広げるか、baselineFrom/baselineToを使って前日の同じ時間帯と比較してください(1日のパターンがあるメトリクスは、直前の数時間と比較すると「異常」に見えることがよくあります)。 - いつ起きたか:
onset_time— 以降の調査では、この時刻を基準点として扱います。 - どこで起きたか:
top_movers— 挙動が変化したラベル値です。単一の動き(1つのポッド、シャード、エンドポイントなど)であれば、原因は局所的と考えられます。すべてが同時に動いていれば、共通の原因(上流の依存先、デプロイ、インフラなど)が考えられます。
3. 対象を絞ったメトリクスクエリで仮説を検証する
query-metrics を使って、レポートから立てた仮説を検証します。
- 動きのあった対象を掘り下げる:疑わしいラベル値を
filtersで指定し、2つ目のキーでグループ化して再クエリします。これにより、ポッドからコンテナー、エンドポイントからステータスコードへと、さらに絞り込めます。 - 正規化する:エラー件数が増えていても、トラフィックが2倍になっていれば意味がありません。
clausesとformula(errors / requests)を使い、量の変化と比率の変化を切り分けます。 - 関連するメトリクスを確認する:同じウィンドウで、関連するメトリクスをクエリします(遅延の場合は、同じサービスのスループットとエラーカウンター、レイテンシーの場合は、リクエストレートと飽和度を示すゲージ)。グリッドを視覚的に揃えるため、同じ
intervalを使います。
4. 発生時刻に合わせて複数のシグナルを関連付ける
同じサービスと、onset_time を挟むウィンドウ(ピーク前の数バケットからピークまで)を使って、ログとトレースを調べます。
- ログ:
query-logs(独自の「検出してから調査する」ワークフローに従います)を使い、該当するservice.nameとウィンドウで絞り込みます。まず重要度errorを確認し、次にwarnを確認します。発生時刻の直前にある再起動、クラッシュループ、接続エラー、デプロイの記録は、典型的な原因です。該当サービス自身のログに問題がなければ、リクエスト経路上の他のサービスにも範囲を広げます。 - トレース: 同じサービスとウィンドウに対して、APM のスパンツール(
query-apm-spansなど)を使います。遅い、またはエラーになっているスパンから、_どの依存先_の状態が悪化したかが分かります。また、エグザンプラーやログ行にあるtrace_idを使えば、具体的なリクエストを3つすべてのシグナルで追跡できます。
5. 印象ではなく、根拠を示して結論を出す
症状(メトリクス、変化の大きさ、発生時刻)、推定される原因(ログやトレースで見つかったことと、そのタイミングが発生時刻とどう一致するか)、影響範囲(動きのあった対象やグループ化したクエリから分かる、影響を受けたサービスやラベル)、確信度を示します。原因がまだ特定できない場合は、根拠がどの仮説を支持しているかと、何を確認すれば区別できるかを述べます(例:「遅延の解消は20:12に始まっており、コンシューマーの再起動と整合します。誰が再起動したか確認してください」)。
作業例:「取り込みの遅延が増えている — なぜか?」
metric-names-listにvalue: "lag"を指定 →logs_rate_limiter_message_lag_seconds(ヒストグラム)などが見つかります。- そのメトリクスに対して
anomalyFrom= アラート時刻としてcharacterize-metric-anomalyを実行 → 方向はup、変化率は 40 倍、onset_timeは 20:10、最も変化した要素はservice_name = logs-ingestion(ほかのサービスの遅延は横ばい)です。つまり、パイプライン全体ではなく、logs のコンシューマーだけが遅れています。 query-metricsで、同じ時間帯におけるコンシューマーのスループットカウンターのrateを確認 → 空白期間中のスループットは ゼロ で、発生時刻の後に急増しています。コンシューマーは遅かったのではなく、停止しており、「遅延の増加」はバックログを処理している状態です。- 20:00~20:15 頃に
service.name = logs-ingestion(および隣接するサービス)のquery-logsを実行 → 空白期間の開始時と終了時に、プロセス終了と再起動のログが確認できます。 - 結論:コンシューマーは 20:01~20:10 に停止していました(ログで再起動を確認)。遅延の急増はバックログの処理によるもので、自動復旧しています。影響を受けたシグナルはログの鮮度のみで、データ損失はありません(トピックにメッセージが保持されていました)。根拠:この期間中のスループットがゼロ、メッセージ経過時間の急増が停止時間と一致、再起動を示すログ行。
注意点
- プロセスの再起動時にカウンターはリセットされます。
rate/increaseはすでにこれに対応しているため、累積カウンターの生値を目視で判断しないでください。 - メトリクスの報告が止まっても、「ゼロ」を意味するわけではありません。
top_moversに消失したラベル値が表示され、seriesに欠損がある場合は、送信元 が停止しています。すぐにログを確認してください。 - 単一の集計値を過信しないでください。横ばいの
avgが、急上昇するp95を隠している場合があります。レイテンシーのようなゲージやヒストグラムでは、テールも分析してください。 - スクレイプされた Prometheus メトリクスは、実時間より約 15~60 秒遅れて届きます。シリーズの最後のバケットを「現在」の値として読み取らないでください。