Agent Mentor Learn
可観測性とデバッグ: エージェントの一歩一歩を見る · 第 4 回 / 全 6 回

レッスン4: トレース: 一度の実行を1本の木につなぐ

学習目標:

  • 相関 ID で散らばった記録を「1つのプロンプトが引き起こした全イベント」にまとめ、セッション ID との分担を説明できる
  • スパンとトレースの階層を読む: ルートスパン、モデルリクエスト、ツール呼び出し、ツールの2段階(権限待ちと実行)、そしてサブエージェントが親エージェントのツールスパンの下にどう入れ子になるか
  • ダッシュボードが空のときはエージェントより先にパイプラインを疑う: エクスポートが静かに失敗する理由、バッチエクスポートがデータを落とす条件、計装そのものを検証する方法

前提: レッスン1〜3(非決定性がなぜ再現を壊すか、生の記録がなぜ第一級の証拠か、ハーネスに構造化ログとメトリクスを組み込む方法) | << レッスン3 | レッスン5 >>

400件の記録、あの1回はどの12件か

前のレッスンの終わりには、あなたのハーネスは runs.jsonl に構造化された記録を書き出していました。モデルリクエストごとに1件、ツール呼び出しごとに1件、所要時間つき、トークンつき、エラーつきです。ログは「1つの大きなテキストの塊」から「1行に1つの JSON オブジェクト」へと変わりました。あなたは満足していました。

そこへユーザーから問題が報告されます。「昨日の午後、ログインページの文言を直してほしいと頼んだら、テストファイルまで変更されました。そんなことは頼んでいません」。

ログを開き、日付で grep すると、400件の記録がこちらを見つめ返してきます。ツール呼び出しが200件、モデルリクエストが100件、そこにサブエージェントの記録が数十件混ざっています。ユーザーが言っているプロンプトは、おそらくそのうちの十数件に対応します。どの十数件でしょうか。

手がかりは2つありますが、どちらも決め手になりません。

  • セッション ID。前のレッスンで確かに全記録に session_id を書きましたが、昨日の午後ユーザーは同じセッション内で7〜8回やり取りしています。セッションで絞ると400件が210件になります。範囲は狭まりますが、性質は同じです。
  • タイムスタンプ。時間帯を推測して切り出すこともできますが、サブエージェントは並行して動いていて、その記録はタイムライン上でメインループの記録と交錯します。しかもユーザーの言う「午後」は14時かもしれず16時かもしれず、本人も覚えていません。

問題は記録の詳しさが足りないことではなく、記録同士に関係がないことです。レッスン3は各ステップをデータに変えましたが、そのデータは並列に並んだ行の山です。どの行がどの行を引き起こしたのか、誰が誰の子なのか、一言も書かれていません。きれいに整形された数百件の JSON オブジェクトも、やはり砂の山のままです。今回はただ、四角い砂になっただけです。

このレッスンでは、その欠けている層を足します。

相関 ID: プロンプトにつける名札

いちばん簡単な一手は、「1つのきっかけとなる出来事」に ID を与え、そのきっかけから生まれたすべてのイベントにその ID をコピーすることです。それが相関 ID です。インフラは一切いりません。ただのフィールドです。

Claude Code のファーストパーティ設計はまさにこれをやっています。ユーザーがプロンプトを送信すると、Claude Code は複数の API 呼び出しを行い、いくつものツールを実行するかもしれません。prompt.id 属性は、それらすべてのイベントを、引き金となった1つのプロンプトに結びつけてくれます1。ドキュメントが示すデバッグの手順も同じくらい直接的です。1つのプロンプトが引き起こしたすべてのアクティビティを追跡するには、特定の prompt.id の値でイベントをフィルタします1

これはセッション ID とは粒度が異なり、それぞれに役割があります。

相関 ID対象範囲答えられる問い
session id会話1本まるごとこのセッションの合計コストはいくらか? 権限モードを変更したか?
prompt idセッション内の1つのプロンプトユーザーが苦情を言っているあの一文は、実際にどのモデルリクエストとツール呼び出しを引き起こしたか?

冒頭の400件に戻りましょう。すべての記録に prompt_id が乗っていれば、セッションのトランスクリプトから「ログインページの文言を直す」に対応する id を見つけ、一度フィルタするだけで400件が12件に落ちます。砂に初めて境界ができます。

しかし境界は構造ではありません。その12件はやはり12行のフラットな行です。誤ったテストファイルの編集がメインループから直接来たのか、それが差し向けたサブエージェントから来たのかは、まだ分かりません。40秒かかったあのツールが、そのうち何秒をあなたの「承認」クリック待ちに費やしたのかも分かりません。

スパンとトレース: イベントを木に並べる

これ以降ずっと使うことになるので、まずいくつかの用語を平易な言葉に置き換えておきます。

  • スパン(span): 「始まりと終わりのある1つの作業」の記録です。名前(llm_request など)、開始時刻、終了時刻を持ち、いくつかの属性(モデル名、ツール名、トークン数)がぶら下がります。スパンは自分の親スパンを指し示せます。
  • トレース(trace): 親子関係でつながったスパンの木全体です。1つの完全なリクエストの間に起きたことすべてを、最初から最後まで木として読むものです。
  • エクスポーター(exporter): プロセス内で、スパンを梱包して外へ送り出す役割のコードです。
  • コレクター(collector): それらのスパンを受け取る中継所やバックエンドサービスです。エクスポーターはここにデータを送り、あなたはそのダッシュボードで木を見ます。

Claude Code の分散トレーシングは、各ユーザープロンプトを、それが引き起こした API リクエストとツール実行に結びつけるスパンをエクスポートします。そのため、リクエスト全体をトレーシングバックエンド上で1本のトレースとして見ることができます1。具体的な階層はこうです。各ユーザープロンプトが claude_code.interaction ルートスパンを開始し、API 呼び出し、ツール呼び出し、フック実行がその子として記録されます。ツールスパンはさらに2つの子スパンを持ち、1つは権限判断を待っていた時間、もう1つは実行そのものです1

ツールの下にあるこの2つの子スパンは、立ち止まって見る価値があります。前のレッスンであなたは duration_ms を記録しました。ツールが40秒動いた、という記録です。しかし「40秒のうち38秒は誰かが承認をクリックするのを待っていた」と「40秒のうち38秒はコマンドを実行していた」は、まったく別の問題です。前者は権限設定を直すかインタラクションの形を変えるという意味であり、後者はツールの実装を直すという意味です。同じ40秒でも、2つに割れば2つの異なる修正が出てきます。これが、フラットなフィールドを超えて木構造が与えてくれるものです。

Agent SDK はもっと直接的に言っています。トレースはエージェントの実行について得られるもっとも詳細なビューであり、CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 を設定すると、エージェントループの各ステップがトレーシングバックエンドで調べられるスパンになります2。CLI には OpenTelemetry の計装が組み込まれています。各モデルリクエストとツール実行の周りにスパンを記録し、トークンとコストのカウンターのメトリクスを出力し、プロンプトとツール結果について構造化されたログイベントを出力します2

これを、このシリーズの第7コース(「エージェントハーネスの基礎: ループと制御」)で書いたハーネスと比べてみてください。あなたのループにはすでに明確な位置があります。「リクエストを送る / tool_use を受け取る / ツールを実行する / tool_result を返す」です。それぞれの位置は自然に1つのスパンに対応します。足りないのは位置ではなく、親子関係です。

境界をまたぐ伝播: サブエージェント、あなたのアプリケーション、Bash サブプロセス

木は見た目こそきれいですが、現実の実行はいくつものプロセス境界をまたぎます。またいだ後も木はつながったままでいられるのでしょうか。いられます。「自分の親は誰か」を下まで受け渡していけばよいのです。

1段下へ: サブエージェント。エージェントが Agent ツール経由でサブエージェントを起動すると、サブエージェントの llm_requesttool のスパンは親エージェントの claude_code.tool スパンの下に入れ子になり、委譲チェーン全体が1本のトレースとして現れます2。これは木がなければ答えられない問いを解決します。サブエージェントのトークンは誰のトークンなのか、という問いです。それはあのツール呼び出しの下に入れ子になっており、そのツール呼び出しはあのプロンプトの下に入れ子になっているので、あのプロンプトのものです。あとから継ぎ足す作業はいりません。

1段上へ: あなたのアプリケーション。SDK は W3C トレースコンテキストを自動的に CLI サブプロセスへ伝播します。W3C トレースコンテキストとは、トレース id と現在のスパン id を含む標準化された文字列にすぎません。受け取った側は、自分をどこにぶら下げればよいか分かります。アプリケーション内で OpenTelemetry のスパンがアクティブな状態で query() を呼ぶと、SDK は子プロセスの環境に TRACEPARENTTRACESTATE を注入し、CLI がそれを読み取って、自分の claude_code.interaction スパンをあなたのスパンの子にします。エージェントの実行は、切り離されたルートとしてではなく、あなたのアプリケーションのトレースの中に現れます2

この違いは本番のトラブルシューティングで非常に実用的です。ユーザーが「あのボタンを押したらページが20秒くるくる回った」と苦情を言ったとき、その HTTP リクエストのトレースに入り、システムを切り替えることもタイムスタンプを突き合わせることもなく、エージェント内部で14秒かかっていたツール呼び出しまで一気に辿れます。

さらに下へ: エージェント自身が実行するコマンド。トレーシングが有効なとき、Bash と PowerShell のサブプロセスは、アクティブなツール実行スパンの W3C トレースコンテキストを含む TRACEPARENT 環境変数を自動的に継承します1。Bash ツール経由で起動されたコマンドが自分自身の OpenTelemetry スパンを出力する場合、それらのスパンはそのコマンドを包む claude_code.tool.execution スパンの下に入れ子になります2

3つの区間をつなげば、1本の木があなたの Web リクエストから始まり、CLI を通り、サブエージェントを通り、エージェントが実行した npm run build の中のコンパイル段階まで伸びていきます。

構造だけを見て、内容は見ない

疑問に思うかもしれません。エージェントの一挙手一投足が外部のバックエンドへ送られるなら、そこにはユーザーが話した内容や、読み書きしたファイルの中身も含まれるのでしょうか。

Anthropic のマルチエージェント研究システムの振り返りは、並び立つ2つの結論を与えています。1つは得られたものです。フルトレーシングを本番に載せた後、彼らはエージェントがなぜ失敗したのかを診断し、問題を体系的に修正できるようになりました3。もう1つは境界です。彼らはユーザーのプライバシーを守るため、個々の会話の内容を監視することなく、エージェントの意思決定パターンとインタラクション構造を監視しました。この高い視点の可観測性だけでも、根本原因の診断、予期しない挙動の発見、よくある失敗の修正に役立ちました3

ファーストパーティのツールのデフォルトの姿勢は、その原則とぴったり一致しています。テレメトリはデフォルトで構造的です。所要時間、モデル名、ツール名はすべてのスパンに記録され、トークン数は下層の API リクエストが使用量データを返したときに記録されるため、失敗またはアボートしたリクエストのスパンではトークン数が欠けることがあります。エージェントが読み書きする内容はデフォルトでは記録されません2。ユーザープロンプトの内容もデフォルトでは収集されず、プロンプトの長さだけが記録されます。内容を含めるには OTEL_LOG_USER_PROMPTS=1 を明示的に設定する必要があります1。Agent SDK のページも、自前の内容収集スイッチの横に同じ注意書きを置いています。あなたの観測パイプラインが、エージェントの扱うデータを保存してよいと承認されていない限り、これらは未設定のままにしておきなさい、というものです2

多くのチームにとってこれは朗報です。「ユーザーのコンテンツをサードパーティのバックエンドに送ってよいか」というコンプライアンス上の戦いに勝ってからでないとエージェントの挙動を見始められない、ということはありません。多くの問題は構造の層で見えます。

自分のハーネス向けにトレースを設計するときは、これをデフォルトにしてください。スパンには名前、所要時間、ツール名、トークン数、エラー種別を記録する。引数や戻り値の内容はローカルの生記録(レッスン2のもの)に置いておき、必要になったら id で引く。

観測パイプライン自身もあなたに嘘をつく

ここまではすべて「木ができた後に何が見えるか」の話でした。この節は、それより手前で起き、より痛い目に遭いやすいことについてです。データを見ているつもりで、実は空のパネルを見ているという事態です。

まず覚えるべきこと。エクスポートの失敗はデフォルトで静かです。エンドポイントに到達できない場合やバックエンドがデータを拒否した場合でも、エージェントは通常どおり動き続け、CLI はアプリケーション側にエラーを表出させることなくテレメトリを捨てます2。この設計は正しいものです。観測パイプラインが本流を巻き添えにしてはいけません。しかしその代償として、パイプラインが壊れている状態と、すべて正常な状態が、あなたの側からは見分けがつきません。

2つ目。バッチエクスポートは特定の条件下でデータを落とします。CLI はテレメトリをバッチにまとめ、一定間隔でエクスポートします。プロセスがクリーンに終了する場合は保留中のデータをフラッシュしようとしますが、そのフラッシュには短いタイムアウトの上限があるため、コレクターの応答が遅ければスパンは依然として落ちる可能性があります。CLI がシャットダウンする前にプロセスが kill されれば、バッチバッファに残っていたものはすべて失われます2。デフォルトでは、メトリクスは60秒ごと、トレースとログは5秒ごとにエクスポートされます2。この2つの文をつなげてみてください。CI で3〜5秒で終わる短命なエージェント実行は、末尾のテレメトリを残せるかどうかを「フラッシュがタイムアウト内に完了し、かつプロセスが早期に kill されないこと」に賭けていることになります。しかもエクスポート間隔はバッファに溜まる量を増幅します。こうしたシナリオでは、実行時間より大幅に短いエクスポート間隔が必要ですし、プロセスがクリーンに終了することを保証する必要があります。

3つ目、そしてトラブルシューティングで最初にやるべきこと。計装そのものを検証する(計装とは、あなたが仕込んだ探針の言い換えにすぎません)。メトリクスをエクスポートする設定を検証するには、バックエンドで claude_code.session.count メトリクスを確認します。これは Claude Code がセッション開始時に出力するものです1。何も届いていなければ、claude --debug を実行し、デバッグログに OTel のエクスポートエラーがないか確認します1。この2ステップの価値は、「エージェントに問題があるのか」と「パイプラインが動いているのか」を、別々に答えられる2つの問いに切り分けられる点にあります。

さらに、踏みやすい設定の落とし穴が2つあります。

  • CLI はデフォルトで service.nameclaude-code として報告します。複数のエージェントを動かす場合や、同じコレクターにエクスポートする他のサービスと並べて SDK を動かす場合は、サービス名を上書きしてリソース属性を追加し、バックエンドでエージェントごとにフィルタできるようにしてください2。そうしないと3つのエージェントのスパンが同じサービス名の下で混ざり、ごった煮を眺めることになります。
  • SDK 経由で実行するときは、エクスポーターの値に console を設定しないでください2。ドキュメントに理由は書かれていませんが、SDK と CLI の通信方式から考えると、SDK は標準出力越しに CLI と話しており、そこにスパンを出力すればそのチャネルが壊れます。

3つのシグナル、必要なものだけ有効化できる

いきなりフルセットを有効にする必要はありません。CLI は3つの独立した OpenTelemetry シグナル、すなわちメトリクス、ログイベント、トレースをエクスポートします。それぞれに固有の有効化スイッチと固有のエクスポーターがあるので、必要なものだけを有効にできます2

ここから自然な導入順序が出てきます。

  1. まずメトリクスを有効にする。コストとトークン使用量は人が最初に聞く質問であり、メトリクスはもっとも安価で、デフォルトの60秒のエクスポート間隔も長時間動くサービスなら問題ありません。
  2. 次にログイベントを有効にする。ツール結果と権限判断、これらの構造化イベントは、レッスン3の診断的な読み方の材料になります。
  3. 説明のつかない問題にぶつかったらトレースを有効にする。もっとも高価でもっとも詳細です。「一度の実行の形を見る」ことが本当に必要になったときに使います。

エクスポート先は OpenTelemetry Protocol(OTLP)を受け付けるバックエンドなら何でもよく、ドキュメントはいくつか名前を挙げています。Honeycomb、Datadog、Grafana、Langfuse、あるいはセルフホストのコレクターです2。どれを選ぶかはこのコースの範囲外です。一言だけ言うと、3つのシグナルが独立しているということは、インフラ一式が揃うのを待たずに、いちばん小さい一片で水を試せるということです。

ついでに: 同じイベント群は監査証跡でもある

構造化イベントには、デバッグとは無関係なもう1つの用途があります。存在だけ知っておいてください。

エンドユーザーの identity が付与されていると、claude_code. で始まる名前のログレコードとしてエクスポートされる tool_decisiontool_resultmcp_server_connectionpermission_mode_changed の各イベントは、SIEM(Security Information and Event Management)プラットフォームへ転送できるユーザー単位の監査証跡になります2。すべてのイベントは、ツール呼び出し、MCP のアクティビティ、権限判断を、それを引き起こしたユーザーへ結びつける identity 属性を持ちます1

同じデータでも、読み方を変えれば別の仕事の材料になります。デバッグのときは prompt.id で横に切り、監査のときはユーザーで縦に切ります。セキュリティの話題はこのコースでは広げません。

このコースが答えを出さないこと

いくつかは境界をはっきりさせておく必要があります。他所に出来合いのレシピを探しに行かないためです。

  • サンプリングレートと保持期間: トレースを全量で保存するとコストがかさむので、どれだけサンプリングし、どれだけ保持するかは現実の問題です。しかし一次資料に指針がないため、このコースは数字をでっち上げません。データ量が本当に問題になったとき、それはあなたとバックエンドの請求書との間の話です。
  • アラートのしきい値: 同じく、数字は示されていません。
  • hooks: ライフサイクルの関所に探針を仕込む方法、PreToolUsePostToolUse がそれぞれ何にアクセスできるかは、レッスン5です。1つだけここで接続口を植えておきます。フックの入力は、現在処理中のユーザープロンプトの UUID を持ち、それはテレメトリイベントの prompt.id 属性と同じ値なので、同一プロンプトについてフックの出力とテレメトリを相関させられます4。このレッスンで確立した相関 ID が、次のレッスンでそのまま使えるようになります。
  • あなた自身のハーネスに OTel フルセットは不要。このレッスンがファーストパーティの設計を教材に使ったのは、あるべき構造をすべて並べて見せてくれるからです。しかしあなたが実際に欲しいのは木だけです。レッスン6では、実行ごとに trace_id を生成し、各記録に span_id と親を指すフィールドを足し、それを十数行のコードでインデント表示します。同じ親子のしくみで作られた木が手に入ります(レッスン6では、ツールについて別の親を選んだ理由も説明します)。コレクターも不要、バックエンドも不要、依存も不要です。もし将来 OTLP に繋ぐ必要が出ても、フィールドはすでに揃っています。

💻 演習

まとめ

  • 構造化ログは「記録が十分詳しいか」を解決しましたが、「記録同士にどんな関係があるか」は解決しませんでした。相関 ID は関係を足す第一歩です。1つのプロンプトが複数の API 呼び出しといくつものツールを引き起こすかもしれず、prompt.id はそれらすべてのイベントを、引き金となった1つのプロンプトに結びつけます。デバッグの初手はこの値でフィルタすることです1
  • スパンは始まりと終わりのある1つの作業の記録であり、トレースは親子関係でつないだ木です。分散トレーシングは各ユーザープロンプトを、それが引き起こした API リクエストとツール実行にスパンとして結びつけるので、リクエスト全体をトレーシングバックエンド上で1本のトレースとして読めます1
  • 階層は決まっています。各プロンプトが claude_code.interaction ルートスパンを開き、API 呼び出し、ツール呼び出し、フック実行がその子になります。ツールスパンは2つの子スパンを持ち、権限待ちの時間と実際に実行していた時間を別々に記録します1。拡張テレメトリを有効にすると、エージェントループの各ステップが調べられるスパンになります。トレースは実行についてもっとも詳細なビューです2
  • 木はプロセス境界をまたいでもつながったままでいられます。サブエージェントのスパンは親エージェントのツールスパンの下に入れ子になり、委譲チェーン全体が1本のトレースとして読めます。SDK は TRACEPARENTTRACESTATE を CLI サブプロセスへ注入するので、エージェントの実行は切り離されたルートではなくあなたのアプリケーションのトレースの中に現れます2。さらに下では、Bash サブプロセスが TRACEPARENT を継承し1、コマンドが出力したスパンはそのツール実行のスパンの下に入れ子になります2
  • フルトレーシングを本番に載せることで、失敗の体系的な診断が可能になります3。そして会話の内容を見ずに意思決定パターンとインタラクション構造だけを監視するだけで、根本原因の診断と予期しない挙動の発見には十分です3。メカニズムもぴったり一致しています。テレメトリはデフォルトで構造的で、所要時間、モデル名、ツール名はすべてのスパンに記録され、内容はデフォルトでは記録されません2。プロンプトの内容もデフォルトでは長さだけの記録で、内容を含めるにはスイッチを明示的に設定する必要があります1
  • メトリクス、ログイベント、トレースは3つの独立したシグナルで、それぞれに固有の有効化スイッチとエクスポーターがあるので、必要なものだけを有効にできます2。段階的に導入でき、一度に全部そろえる必要はありません。
  • 観測パイプライン自身もあなたに嘘をつきます。エクスポートの失敗はデフォルトで静かで、エージェントは通常どおり動く一方でテレメトリは捨てられ、エラーは表出しません2。バッチエクスポートはクリーンな終了時にフラッシュを試みますが、短いタイムアウトに制限され、プロセスが kill されればバッファは丸ごと失われます2。デフォルトではメトリクスは60秒ごと、トレースとログは5秒ごと2なので、短命な実行にはより短い間隔が必要です。トラブルシューティングの最初の一手は計装そのものを検証することです。バックエンドであのセッション数のメトリクスを確認し1、なければ --debug を有効にしてエクスポートエラーを見ます1
  • 設定の落とし穴が2つ。複数のエージェントが1つのバックエンドを共有する場合は、service.name を上書きしてリソース属性を追加しないと区別できません2。SDK 経由で実行するときはエクスポーターに console を設定しないでください2
  • 同じ構造化イベントも、読み方を変えれば監査の材料です。identity 属性が付けば、ツールの判断、ツールの結果、MCP の接続、権限モードの変更は SIEM へ転送できるユーザー単位の監査証跡になり2、各イベントの identity 属性がツール呼び出しをそれを引き起こした人へ結びつけます1
  • サンプリングレートと保持期間には一次資料の指針がないので、このコースは数字を出しません。あなた自身のハーネスも OTel フルセットに乗る必要はありません。レッスン6では trace_id と親を指すフィールドとインデント表示だけで、同じ親子のしくみで作られた木を手に入れます。

>> レッスン5: 関所に探針を置く: hooks と原因特定のフロー

Footnotes

  1. Monitoring — Claude Code Official Documentation — https://code.claude.com/docs/en/monitoring-usage 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

  2. Observability with OpenTelemetry — Claude Agent SDK Official Documentation — https://code.claude.com/docs/en/agent-sdk/observability 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

  3. How we built our multi-agent research system — Anthropic Engineering — https://www.anthropic.com/engineering/multi-agent-research-system 2 3 4

  4. Hooks reference — Claude Code Official Documentation — https://code.claude.com/docs/en/hooks

練習

01

以下はエージェントの実行から取った14件のスパン記録で、1行に1つの JSON オブジェクトです。終了時刻順に書かれている(スパンは終わるまで自分の所要時間を知らない)ので、子が親より先に現れることがよくあります。

レベル1: 14件のフラットな記録を木に描く

問題を短く保つため、各ツールの「権限待ち」の子記録はツール記録の wait_ms フィールドに畳み込み、実行の子記録だけを残しました。end_ms はこの実行の開始からのミリ秒です。

コードを書かずに、紙とペンかテキストエディタで次を完成させてください。

  1. これら14件の記録をインデントしたトレースツリーとして再構築します。同じ階層の兄弟は上から下へ開始時刻順に並べます(開始時刻 = end_ms - dur_ms)。各行には名前と所要時間を表示し、ツールにはツール名を書き添えます。
  2. 答えてください: この実行で、サブエージェントが消費したトークンはどのプロンプトに計上されますか。なぜですか。そのプロンプトの合計トークンを計算してください。
  3. 答えてください: build.compile2回目のツール呼び出しから引き起こされたことを証明できる記録はどれ1件ですか。どのフィールドの、値のどの部分かまで指定してください。
完了基準 · ローカルでチェック
02

コードは書きません。以下の3つのシナリオはどれも「ダッシュボードの様子がおかしい」という見た目をしていますが、下にあるメカニズムは3つとも別物です。それぞれについて、もっとも可能性の高い原因、どの順序で検証するか、検証を通った後どう対処するかを書いてください。すべての判断は、このレッスンで扱った具体的なメカニズムに戻れるものでなければなりません。何でも「設定ミス」で片づけないでください。

レベル2: 3つの空のダッシュボード、それぞれに調査経路を示す
  • シナリオA: テレメトリのエクスポートを接続してリリースし、1週間が経ちましたが、ダッシュボードにはデータがまったくありません。スパンもメトリクスもイベントもゼロです。エージェントは1週間ずっと通常どおりユーザーに使われていて、誰からも苦情はありません。
  • シナリオB: メトリクスのパネルはまったく正常です。トークン数は増えていて、コストの曲線も動いていて、セッション数も辻褄が合います。しかしトレーシングバックエンドを開いて今日の時間範囲で検索すると、トレースが1本もありません。
  • シナリオC: CI で動く短いスクリプトで、終わるたびにトレースの「尻尾が欠けて」います。ルートスパンはあり、最初の数ステップもありますが、最後の2〜3件のツールスパンが消えています。同じ設定でもローカルの開発マシンで長時間実行すると、すべて問題なく表示されます。
完了基準 · ローカルでチェック