テックブログ

OpenTelemetryでトレースが届かない原因と確認手順

OpenTelemetryでトレースが届かない原因と確認手順

OpenTelemetryのトレースは、アプリケーションでSpanが生成され、Exporterから送信され、必要に応じてCollectorを経由し、バックエンドで保存・検索されます。この経路のどこかで問題が発生すると、アプリケーション自体は正常に動作していても、トレースが監視画面に表示されないことがあります。しかし、画面に何も表示されないという結果だけでは、Spanが生成されていないのか、通信に失敗しているのか、Collectorで除外されたのかを判断できません。

原因を特定するには、実際のテスト要求を発生させ、Spanの生成、送信、受信、加工、保存、検索という各段階にデータが存在するかを順に確認することが重要です。Java Agentのコンソール出力やデバッグログ、Collectorのdebug exporter、内部メトリクスを利用すると、どの段階まで正常に処理されたかを確認できます。また、サンプリングによる意図的な除外や、バッチ処理による送信待ちを通信障害と区別する必要もあります。確認対象を一つずつ絞り、観測できた最後の地点を特定することで、不要な設定変更を避けながら原因を調査できます。

1. 「表示されない」を調査できる事実へ変える

経路とテスト要求を固定する

最初に、アプリケーションから監視画面までの実際のデータ経路を書き出します。OpenTelemetryでは、アプリケーションがバックエンドへ直接トレースを送信する構成と、Collectorを経由して送信する構成があります。どちらを使用しているかによって、確認すべき設定やログが異なります。

たとえば、Java AgentからCollectorへOTLPで送信し、Collectorが加工したトレースをバックエンドへ転送する構成では、アプリケーション、Collectorの受信処理、processor、exporter、バックエンドの各段階が調査対象になります。一方、Agentがバックエンドへ直接送信している場合、Collectorの設定を調べても原因は見つかりません。

特に注意したいのが、設定ファイルに記載された経路と、実際に動作している経路が一致しているとは限らないことです。たとえばCollectorの設定ファイルを編集していても、アプリケーション側のExporterが別のCollectorやバックエンドへ直接送信していれば、その変更はトレースの送信先に影響しません。

調査を始める前に、送信元のサービス、送信先のホスト名とポート、使用するプロトコル、途中のプロキシやロードバランサーを整理します。複数のCollectorを使用している場合は、どのインスタンスを経由しているかも確認します。

次に、計測対象のHTTP APIを実際に呼び出し、呼び出した時刻、環境、サービス名、操作内容を記録します。Spanとは、一つの処理区間の開始時刻や終了時刻などを表すデータです。アプリケーションが起動しているだけでは、調査したいAPIに対応するSpanが生成されたとは判断できません。

テスト要求には、できるだけ再現しやすい処理を選びます。たとえば検証環境の注文照会APIや商品検索APIなど、業務データの更新を伴わず、繰り返し呼び出しても影響が小さい処理が適しています。

ヘルスチェック用のAPIは、監視上の重要性が低いとして計装や収集の対象から除外されている場合があります。そのため、ヘルスチェックの結果だけを使って、トレース収集全体が正常かどうかを判断することは避けます。

テスト要求を実行したら、同時刻のアプリケーションログとCollectorログを確認します。ログにTrace IDが含まれていれば、以降はそのIDを共通の手掛かりとして使用します。Trace IDは、一つの分散トレースを識別するための値であり、複数サービスをまたぐ処理でも同じIDを引き継ぐことで、関連するSpanをまとめて追跡できます。

Trace IDが確認できない場合は、まずリクエスト時刻、対象URL、サービス名などで範囲を絞ります。時刻だけで追跡する場合は、サーバー間の時計のずれやタイムゾーンの違いにも注意が必要です。

このように、一つの再現可能な要求を基準にすると、設定変更前後の結果を比較しやすくなります。闇雲に大量のリクエストを送るのではなく、同じ操作を繰り返し、各段階で何が変わったかを確認することが重要です。

全件不在と一部の欠落を分ける

トレースが見つからない場合は、まずすべてのトレースが表示されないのか、一部のトレースだけが欠落しているのかを区別します。この違いによって、優先して調査すべき原因が変わります。

すべてのトレースが表示されない場合は、Agentが読み込まれていない、Exporterが無効化されている、送信先が間違っている、Collectorが起動していない、検索先の環境が異なるといった、経路全体に影響する設定を優先して確認します。

一方、一部のリクエストだけが見つからない場合は、サンプリング、特定ライブラリの計装、処理分岐、Spanの終了漏れ、検索条件などが候補になります。すべてのトレースが正常に送信されるとは限らないため、個別のTraceが存在しないことだけで通信障害と判断しないようにします。

たとえば、通常のリクエストは表示されるのに、特定のバッチ処理だけが表示されない場合、そのバッチ処理に対応する計装が存在しない可能性があります。また、短時間の処理は表示されるのに、アプリケーションを停止した直前の処理だけが見つからない場合、送信待ちのSpanが残っていた可能性があります。

発生条件も重要な手掛かりです。「昨日までは正常だった」「特定のサービスだけ表示されない」「アクセス集中時だけ欠落する」といった条件を記録すると、調査対象を絞りやすくなります。

特に、問題が発生する直前に設定変更やバージョンアップを行っていた場合は、その差分を確認します。Java Agentのバージョン、Collectorの設定、起動引数、環境変数、認証情報、ネットワーク構成などが比較対象です。

ただし、直前の変更が必ず原因とは限りません。たとえばAgentの更新と同じ時期にバックエンド側の認証情報が期限切れになった場合、Agentの変更だけを調べても解決できません。変更履歴を手掛かりにしつつ、実際のログやメトリクスで確認します。

また、調査記録に含める情報にも注意が必要です。接続先のホスト名、ポート、プロトコル、環境変数のキーなどは比較に役立ちますが、認証トークンやAPIキーの実値をそのまま記録する必要はありません。

設定ファイルを丸ごとチャットやチケットに貼り付けると、調査に不要な秘密情報まで共有する可能性があります。設定項目の有無と、安全に比較できる値を分けて整理し、必要に応じて機密情報を伏せて記録します。

2. アプリ側でSpanが生成されているか確かめる

Java Agentとローカル出力を確認する

アプリケーション側の確認では、まずJava Agentが実際に読み込まれているかを調べます。OpenTelemetry Java Agentは、Javaアプリケーションの起動時に指定することで、対応するライブラリやフレームワークの処理を自動的に計装します。

たとえばSpring BootでHTTP APIを提供している場合、対応するライブラリが使用され、計装が有効であれば、受信したHTTPリクエストに関するSpanを自動生成できます。また、対応するHTTPクライアントやDBアクセス用ライブラリを使用している場合、それらの処理に対応するSpanが生成されることもあります。

ただし、AgentのJARファイルが配置されているだけでは計装は有効になりません。Javaプロセスの起動時に-javaagentオプションを指定する必要があります。

コンテナ環境では、Dockerfileや起動スクリプトを編集していても、実際に動作しているコンテナが古いイメージのままである可能性があります。設定ファイルの内容だけでなく、現在起動しているJavaプロセスの引数やAgentの起動ログを確認することが重要です。

また、使用しているJava Agentのバージョンと、アプリケーションが利用するライブラリの対応状況も確認します。Java Agentは多くのライブラリに対応していますが、すべてのJavaコードが自動的に計装されるわけではありません。

Agentが読み込まれていることを確認できたら、次にSpanが実際に生成され、出力されているかを調べます。このとき、バックエンドへの送信を一時的に切り離し、ローカルへ出力する方法が有効です。

検証用の別プロセスでトレースの出力先をコンソールへ変更すると、ネットワークやCollectorを経由せずに、Agent側の計装結果を確認できます。

以下はOpenTelemetry Java Agent 2.xを使用した検証例です。実在するHTTP APIを持つapp.jarと、指定したパスに配置されたAgentのJARファイルを用意している前提です。

OTEL_SERVICE_NAME=trace-check \
OTEL_TRACES_EXPORTER=console \
OTEL_TRACES_SAMPLER=always_on \
OTEL_METRICS_EXPORTER=none \
OTEL_LOGS_EXPORTER=none \
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -jar app.jar

OTEL_SERVICE_NAMEは、トレース上でアプリケーションを識別するサービス名です。この例では検証用としてtrace-checkを指定しています。

OTEL_TRACES_EXPORTER=consoleは、トレースデータを標準出力へ出力する設定です。通常のOTLP送信とは異なり、Collectorやバックエンドへ送信する前の段階を確認するために使用します。

OTEL_TRACES_SAMPLER=always_onは、サンプリングによる除外を避けるための設定です。通常の設定で一部のTraceが除外されている可能性を切り離し、検証対象のSpanが生成されるかを確認します。

また、OTEL_METRICS_EXPORTER=noneとOTEL_LOGS_EXPORTER=noneによって、この検証ではOpenTelemetryのメトリクスとログのエクスポートを無効にしています。調査対象をトレースに絞るための設定であり、アプリケーション自身が出力する通常のログを必ず停止するものではありません。

この状態でテスト要求を送信し、処理終了後にコンソール出力を確認します。Spanが表示されれば、少なくともこの検証設定では、計装、Spanの終了、ローカルへの出力まで進んだと判断できます。

ただし、コンソールに出力されたことは、通常のOTLP送信が成功することを意味しません。また、出力先を変更しているため、元の構成でも同じ結果になるとは限りません。

さらに、コンソール出力にはSpanの属性やイベントが含まれることがあります。リクエストに個人情報や認証情報が含まれる環境では、それらが出力されないよう注意し、安全な検証データだけを使用します。

記録対象とサンプリングを確認する

コンソールにもSpanが出力されない場合は、テスト要求が実際に計装対象の処理を通過したかを確認します。Java Agentが読み込まれていても、対象ライブラリが対応していなかったり、特定の計装が無効化されていたりすると、期待したSpanが生成されない場合があります。

自動計装は、主に対応するライブラリやフレームワークの処理を対象とします。そのため、独自に実装した業務メソッドを呼び出しても、そのメソッド名に対応するSpanが必ず生成されるわけではありません。

たとえば、注文APIのHTTPリクエストに対応するSpanは表示されていても、内部のcalculateOrderTotal()という業務メソッドに対応するSpanが表示されない場合があります。これは必ずしも異常ではなく、そのメソッドが自動計装の対象ではない可能性があります。

独自処理の詳細なSpanが必要な場合は、OpenTelemetry APIによる手動計装などを検討します。ただし、トレースが届かない問題の調査中に計装対象を無闇に増やすと、原因の切り分けが難しくなります。まず既存の計装で生成されるはずのSpanを確認することが重要です。

手動計装を使用している場合は、Spanの終了処理も確認します。Spanは開始しただけでは通常のエクスポート対象として完成せず、終了時にSpanProcessorへ渡されます。例外が発生した場合などにend()が実行されない実装では、Spanが送信されない原因になる可能性があります。

次に、サンプリングの設定を確認します。OpenTelemetryでは、サンプラーによって記録対象から除外されたSpanは、通常のトレースデータとしてエクスポートされません。

特にParentBasedサンプラーを使用している場合は、上流サービスから引き継いだサンプリング判断にも注意が必要です。上流で記録対象外と判断されたTraceを下流が引き継ぐと、下流サービスでもSpanが記録・送信されない場合があります。

この場合、アプリケーションログにTrace IDが表示されていても、バックエンドでトレースを検索できるとは限りません。Trace IDが存在することと、対応するSpanがエクスポートされることは別の判断です。

通常設定ではSpanが見つからず、always_onを使用した検証設定では表示される場合、サンプリング設定が原因候補になります。ただし、ほかの設定も同時に変更している場合は、サンプリングだけが原因だったと断定できません。

また、短時間で終了するプロセスでは、Spanが生成されていてもExporterへ送信される前にプロセスが終了する場合があります。

OpenTelemetry Java SDKでは、終了済みのSpanを一定間隔でまとめて送信するBatch Span Processorが利用されます。標準的な設定では送信間隔が5,000ミリ秒となっているため、Spanの終了直後に必ず送信が完了するわけではありません。

正常終了時にはSDKのシャットダウン処理によって未送信データの処理が行われますが、強制終了や異常終了でもすべてのSpanが保存されるとは限りません。短時間のバッチ処理や検証用プログラムでは、終了方法と送信タイミングも確認します。

さらに詳細なAgentの動作を調べる場合は、OTEL_JAVAAGENT_DEBUG=trueを使用できます。ただし、デバッグログは大量に出力される可能性があるため、対象プロセスと確認期間を限定します。調査後は設定を元に戻し、不要なログ出力を継続しないようにします。

3. OTLPの送信先と到達性を照合する

方式、ポート、パスを一組で確認する

アプリケーション側でSpanが生成されていることを確認できたら、次はExporterの送信先を調べます。OpenTelemetryでは、テレメトリーデータの転送にOTLP(OpenTelemetry Protocol)が使用されます。

OTLPには主にgRPCとHTTPの通信方式があり、一般的な既定ポートはgRPCが4317、HTTPが4318です。ただし、これらは標準的な設定で使用されるポートであり、実際の環境では別のポートを使用している場合があります。

通信方式を確認するときは、ポート番号だけで判断しないことが重要です。たとえば4318番ポートを指定していても、Collector側でHTTP receiverが有効になっていなければ通信できません。送信側のプロトコル、接続先のポート、Collectorの待受設定を一組として確認します。

また、Java Agent 2.0以降では、OTLPの既定プロトコルがhttp/protobufになっています。OpenTelemetry SDK一般の説明や古い設定例ではgRPCを前提としているものもあるため、使用しているAgentのバージョンを確認する必要があります。

OTLP/HTTPでは、endpointの指定方法によって送信先のURLが変わります。特に、共通endpointとトレース専用endpointでは、パスの扱いが異なります。

OTEL_EXPORTER_OTLP_ENDPOINTは、トレース、メトリクス、ログなどで共通して使用するベースURLを指定します。OTLP/HTTPでこの変数を使用した場合、トレースの送信時には通常/v1/tracesが追加されます。

一方、OTEL_EXPORTER_OTLP_TRACES_ENDPOINTは、トレース専用のURLを直接指定します。こちらは指定したURLをそのまま使用するため、通常は/v1/tracesまで含めて設定します。

送信方式・設定ローカル検証での指定例照合する点
HTTPの共通endpointhttp://127.0.0.1:4318共通設定から/v1/tracesが追加される
HTTPのtraces endpointhttp://127.0.0.1:4318/v1/traces指定したURLをそのまま使用する
gRPCのendpointhttp://127.0.0.1:4317HTTP用の/v1/tracesを付けない

たとえば、共通endpointにhttp://127.0.0.1:4318を指定した場合、トレースは通常http://127.0.0.1:4318/v1/tracesへ送信されます。

しかし、トレース専用endpointにhttp://127.0.0.1:4318だけを指定した場合、送信先は通常ルートパスになります。意図した/v1/tracesへ送信されず、HTTP 404などのエラーにつながる可能性があります。

また、信号別の設定は共通設定より優先されます。たとえばOTEL_EXPORTER_OTLP_ENDPOINTを正しいCollectorへ変更しても、古いOTEL_EXPORTER_OTLP_TRACES_ENDPOINTが残っていれば、トレースだけが以前の接続先へ送信される可能性があります。

Java Agentで設定を確認する際は、環境変数だけでなくJVMシステムプロパティにも注意が必要です。Java Agentではシステムプロパティが環境変数より優先されるため、環境変数を変更しても、起動引数の-Dで別の値が指定されていれば、変更が反映されないことがあります。

ローカルのCollectorへOTLP/HTTPで送信する場合は、たとえば次のように指定します。

OTEL_SERVICE_NAME=trace-check \
OTEL_TRACES_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces \
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -jar app.jar

この例では、トレースの出力先をOTLPに設定し、通信方式とトレース専用endpointを明示しています。Collectorが同じネットワーク名前空間で起動し、指定したポートでOTLP/HTTPを受信できることが前提です。

なお、この例ではサンプラーやメトリクス、ログのExporterは明示していません。検証目的に応じて必要な設定を追加し、既存の環境変数やシステムプロパティが意図しない値を指定していないことを確認します。

設定変更後はJavaプロセスを再起動し、変更後の値が実際に使用されていることを確認します。設定ファイルを書き換えただけで、実行中のプロセスへ変更が反映されるとは限りません。

エラーを手掛かりにネットワークを調べる

送信先の設定が正しく見える場合でも、アプリケーションからCollectorへ通信できるとは限りません。ネットワークの到達性は、必ずアプリケーションが実行されている環境から確認します。

たとえば、自分のPCからCollectorへ接続できても、アプリケーションが動作するサーバーやコンテナから同じ宛先へ接続できるとは限りません。DNSの設定、ファイアウォール、ネットワークポリシー、プロキシ、TLS証明書などの条件が異なるためです。

特にコンテナ環境では、localhostの扱いに注意が必要です。localhostや127.0.0.1は、通信を実行している環境自身を指します。

たとえばアプリケーションとCollectorが別々のDockerコンテナで起動している場合、アプリケーション側で127.0.0.1:4318を指定すると、通常はアプリケーション自身のコンテナへ接続しようとします。Collectorが別のコンテナで動作していても、自動的にそのCollectorへ接続されるわけではありません。

この場合は、コンテナ間で名前解決できるサービス名や、実際に到達可能なアドレスを指定する必要があります。Kubernetesでも、Podの構成やServiceの設定に応じて接続先を確認します。

Exporterのログに通信エラーが出ている場合は、その内容から原因候補を絞ります。

症状の例最初に確認する候補
connection refused指定先の待受プロセス、ポート、コンテナのポート公開
名前解決の失敗アプリ側のDNS、サービス名、ネットワークへの接続
タイムアウト経路の遮断、接続先の遅延、プロキシ、処理量
HTTP 404URLのパス、リバースプロキシの経路、接続先の取り違え
HTTP 401・403必要な認証、権限、テナント指定
HTTP 429送信先のレート制限、受信容量
HTTP 503送信先の一時的な利用不可、過負荷、経路上の問題
証明書の検証失敗ホスト名、信頼するCA、有効期限、TLS設定

たとえばconnection refusedが発生している場合、指定したホストとポートへ接続を試みたものの、接続が拒否された可能性があります。Collectorが停止している、指定したポートで待ち受けていない、別のアドレスにのみバインドされているといった原因が考えられます。

一方、タイムアウトが発生している場合は、ネットワーク経路で通信が遮断されている可能性に加え、Collectorやバックエンドの応答が遅れている可能性もあります。単にタイムアウト値を長くするのではなく、応答が返らない理由を確認する必要があります。

HTTP 401や403が返される場合は、認証情報やアクセス権限を確認します。クラウド上の監視サービスや認証付きのゲートウェイを経由している場合、OTLPの送信時にAPIキーや認証ヘッダーなどが必要になることがあります。

ただし、エラーメッセージだけで原因を確定することはできません。たとえばHTTP 404が返されていても、Collector自身ではなく、途中のリバースプロキシが応答している可能性があります。ログの時刻と実際の送信先を照合し、どの機器が応答したかを確認します。

curlなどを利用した接続確認も有効ですが、確認できる範囲には限界があります。TCP接続が成功したとしても、有効なOTLPペイロードを正常に受信・処理できることまでは保証されません。

また、OTLP/HTTPでトレースを送信する場合、通常は対応するペイロードを持つPOSTリクエストを使用します。そのため、GET /v1/tracesがエラーになることだけで、OTLPの受信設定が壊れていると判断してはいけません。

ネットワークの到達性を確認する試験と、実際にSpanを送信してCollectorが受信できるかを確認する試験は分けて実施します。接続できることと、トレースが正常に取り込まれることは別の確認項目です。

4. Collectorの入口と出口に証拠を置く

最小の経路で受信を確認する

アプリケーションから送信しているにもかかわらずトレースが見つからない場合、次はCollectorが実際に受信できているかを調べます。

Collectorは、receiver、processor、exporterなどのコンポーネントを組み合わせてデータを処理します。receiverが外部からデータを受け取り、processorが必要に応じて加工や選別を行い、exporterが後段へ送信します。

ただし、これらのコンポーネントを設定ファイルに定義しただけでは、必ずしも有効になりません。Collectorでは、service.pipelinesに使用するコンポーネントを登録する必要があります。

たとえばOTLP receiverを定義していても、traces pipelineで使用していなければ、意図した経路でトレースを処理できません。また、メトリクス用のpipelineだけが定義されている場合、トレースを処理するpipelineが存在しない可能性があります。

さらに、設定ファイルを編集しても、実際にCollectorが読み込んでいるファイルが異なれば変更は反映されません。特にコンテナやサービス管理ツールを使用している環境では、マウント先、起動引数、設定配布の仕組みを確認する必要があります。

Collectorへの受信を確認する方法として、debug exporterを使用した最小構成が有効です。debug exporterは、Collectorが処理したテレメトリーデータをログへ出力するためのコンポーネントです。

以下は、アプリケーションとCollectorを同じネットワーク名前空間で動作させるローカル検証用の設定例です。

receivers:
  otlp:
    protocols:
      http:
        endpoint: 127.0.0.1:4318

exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [debug]

この設定では、OTLP/HTTPで受信したトレースを、加工用のprocessorを経由せずにdebug exporterへ渡します。後段のバックエンドへの通信も行わないため、Collectorの受信処理を比較的単純な構成で確認できます。

verbosity: detailedは、Spanの詳細情報を出力する設定です。Trace ID、Span ID、Span名、開始・終了時刻、属性などを確認できるため、テスト要求に対応するデータが届いたかを判断しやすくなります。

設定ファイルをotelcol-check.yamlとして保存した場合、次のように設定を検証できます。

otelcol validate --config=otelcol-check.yaml

設定に問題がなければ、次のコマンドでCollectorを起動します。

otelcol --config=otelcol-check.yaml

使用するCollectorの配布版によって実行ファイル名は異なります。また、otlp receiverとdebug exporterが配布版に含まれている必要があります。必要なコンポーネントが含まれているかは、otelcol componentsなどで確認できます。

なお、validateコマンドで確認できるのは主に設定の妥当性です。構文やコンポーネントの設定が正しくても、ネットワーク接続やデータ受信が成功するとは限りません。

Collectorを起動したら、アプリケーションからテスト要求を送信し、Collectorのログに対応するSpanが表示されるかを確認します。

このとき、Trace ID、Span名、サービス名、時刻を記録します。特にTrace IDが一致していれば、アプリケーションで生成されたトレースが、Collectorの受信経路を通過してdebug exporterまで届いたと判断できます。

一方、ログにSpanが表示されない場合は、アプリケーション側の送信先、Collectorの待受アドレス、プロトコル、ポートを再確認します。

ただし、この検証でSpanが表示されても、元の本番pipelineやバックエンドへの送信が成功したことにはなりません。あくまで最小構成でCollectorが受信できたという証拠です。

また、別コンテナから接続する場合は、127.0.0.1で待ち受ける構成のままでは接続できないことがあります。実際のネットワーク構成に合わせて待受アドレスを検討し、不要な外部公開を避けます。

詳細なdebug出力には機密性のある属性が含まれる可能性があるため、安全な検証データのみを使用します。恒常的な本番設定として詳細出力を有効にし続けないようにしてください。

内部メトリクスで通過量を確認する

最小構成で受信できることを確認したら、次は通常のCollector構成でデータがどこまで処理されているかを調べます。

この確認には、Collector自身が出力する内部メトリクスを利用できます。内部メトリクスは、Collectorの受信数、送信数、処理失敗、キューの状態などを確認するための情報です。

アプリケーションから収集する業務メトリクスとは異なり、Collector自身の状態を監視するための仕組みです。Collectorの内部テレメトリーは、通常のトレース用pipelineとは別に設定されます。

Collectorでは、標準的な構成で内部メトリクスをPrometheus形式で公開できます。既定では127.0.0.1:8888/metricsで確認できる構成が案内されていますが、使用するバージョンや設定によって公開方法が異なる場合があります。

確認対象となる代表的な指標は次のとおりです。

指標確認に使う意味
otelcol_receiver_accepted_spanspipelineへ正常に渡されたSpan数
otelcol_receiver_refused_spanspipelineへ渡せなかったSpan数
otelcol_exporter_sent_spansexporterが正常に送信したSpan数
otelcol_exporter_send_failed_spansexporterの送信が失敗したSpan数
otelcol_exporter_queue_size送信待ちキューの使用状況
otelcol_exporter_queue_capacity送信待ちキューの容量

たとえばテスト要求を実行した後、otelcol_receiver_accepted_spansが増加していれば、CollectorがSpanを受信し、pipelineへ渡したことを確認できます。

一方、この値が増加せず、アプリケーション側では送信を試みている場合、通信経路やreceiverの設定を優先して確認します。ただし、複数のCollectorが存在する場合は、実際の送信先とは別のインスタンスを監視していないかにも注意が必要です。

receiverでSpanを受信しているのにotelcol_exporter_sent_spansが増加しない場合は、processorで除外されている、batch処理で待機している、exporterが正常に送信できていないなどの可能性があります。

このとき、受信数と送信数が一致しないことだけで障害と判断してはいけません。filterやsamplingで意図的にSpanを除外する構成では、入口より出口の件数が少なくなることがあります。

また、複数のexporterへ同じデータを送信する構成では、送信数の合計が受信数を上回る場合もあります。メトリクスを比較するときは、対象のreceiver、exporter、Collectorインスタンスをそろえる必要があります。

otelcol_exporter_send_failed_spansが増加している場合は、後段への送信が失敗している可能性があります。ただし、Exporterには再試行の仕組みがあるため、送信失敗が記録されたことが、そのまま最終的なデータ欠落を意味するわけではありません。

一時的な接続障害が発生しても、再試行によって後から正常に送信される場合があります。失敗数だけでなく、送信成功数やキューの状態、バックエンドでの受信結果も合わせて確認します。

キューの使用状況を表すotelcol_exporter_queue_sizeが増加し続ける場合、後段への送信が受信量に追いついていない可能性があります。キューの容量を超えると、新しいデータを保持できず、欠落につながる場合があります。

なお、キューサイズは構成によってバッチやリクエスト単位で管理されるため、値をそのままSpan数と解釈しないようにします。

内部メトリクスの名称、出力形式、公開条件はCollectorのバージョンによって変わる場合があります。特に、内部テレメトリーの設定方法には変更が加えられているため、古い設定例を無条件に流用しないことが重要です。

5. 加工と保存・検索の条件を調べる

processorと後段の送信を切り分ける

最小構成ではSpanが表示されるのに、通常のCollector構成ではトレースが届かない場合、両者の設定差分を確認します。

Collectorでは、receiverとexporterの間にprocessorを配置し、データの加工や選別を行うことができます。processorは正常に動作していても、設定内容によって特定のSpanを除外する場合があります。

たとえばfilter processorを利用してヘルスチェックのSpanを除外している場合、ヘルスチェックのトレースがバックエンドに表示されないのは意図した動作です。

また、sampling processorによって一定割合のTraceだけを保存する構成では、テスト要求が保存対象から外れる可能性があります。特に少数のリクエストで検証している場合、設定が正しくても対象のTraceが一件も残らないことがあります。

そのほか、memory limiterによる受信データの拒否、batch processorによる送信待ち、exporterの送信先や認証設定なども原因候補です。

代表的な確認対象を整理すると、次のようになります。

コンポーネント確認する内容起こり得る現象
filter processor除外条件、対象属性特定のSpanが表示されない
sampling processor抽出率、保存条件一部のTraceが保存されない
memory limiterメモリ使用量、制限設定高負荷時に受信データが拒否される
batch processorバッチサイズ、送信間隔送信まで時間差が発生する
exporter宛先、認証、TLS、キュー後段への送信に失敗する

調査では、これらの設定を一度に変更するのではなく、検証用の構成でprocessorを一つずつ追加し、同じテスト要求を送信します。

たとえば最小構成では表示されるものの、filter processorを追加すると特定のSpanが表示されなくなる場合、そのfilter条件が原因候補になります。

一方、filter processorを追加しても正常に表示され、sampling processorを追加した段階で欠落する場合は、サンプリング条件を確認します。

この方法では、どの設定を追加した段階で結果が変わったかを明確にできます。ただし、元の構成で複数のprocessorが相互に影響している場合、単体の動作確認だけでは原因を特定できないこともあります。必要に応じて、processorの順序や組み合わせも確認します。

また、通常pipelineの末尾へdebug exporterを追加するだけでは、すべてのSpanを確認できるわけではありません。前段のprocessorで除外されたSpanは、その後のexporterへ渡されないためです。

processorを外して検証する場合は、対象データの扱いにも注意が必要です。たとえば機密情報を削除するprocessorを無効にすると、本来バックエンドへ送信しないはずの属性が残る可能性があります。

そのため、processorを無効化した試験では、検証専用の環境と無害なテストデータを使用します。本番環境の実データをそのまま転送しないようにします。

さらに、Collectorへの到着後にサンプリング判断を行う構成では、すぐに検索してもTraceが表示されない場合があります。テールサンプリングでは一定時間Spanを保持してから判断するため、バックエンドへ送信されるまでに時間差が生じます。

このような待機時間による表示遅延と、恒久的な欠落は区別する必要があります。送信直後に見つからないという理由だけで設定を変更せず、想定される待機時間を経過した後に再確認します。

ただし、待機時間を過ぎても表示されず、送信失敗やキューの増加が続く場合は、後段の接続先やCollectorの処理能力を確認します。

単にキュー容量やタイムアウトを増やしても、送信先が間違っている場合や認証情報が無効な場合は解決しません。まず失敗原因を確認し、必要な設定を修正することが重要です。

受信成功と画面への表示を分ける

CollectorのExporterで送信成功が確認できても、バックエンドの検索画面に必ず表示されるとは限りません。Collectorからの送信と、バックエンドでの保存・検索は別の段階だからです。

たとえばCollectorが正常にHTTPリクエストを送信し、バックエンドから成功応答を受け取った場合でも、実際に検索可能になるまでに時間がかかることがあります。

また、OTLPでは一部のデータだけが受け付けられる部分成功という応答も定義されています。OTLP/HTTPではHTTP 200が返されても、応答内容に拒否されたSpan数が含まれる場合があります。そのため、HTTPステータスコードだけで全件が保存されたと判断しないようにします。

バックエンド側を確認するときは、まず送信先の環境、プロジェクト、テナントが正しいかを調べます。監視サービスによっては、認証情報や送信先の設定によって保存先が変わる場合があります。

たとえば検証環境のCollectorが本番環境とは別のプロジェクトへ送信している場合、Collector側の送信が成功していても、本番用の検索画面には表示されません。

次に、検索条件を確認します。特に時間範囲、タイムゾーン、サービス名、保持期間は、検索結果に大きく影響する項目です。

たとえばアプリケーション側でservice.nameを変更した場合、以前のサービス名で検索しても新しいTraceは見つかりません。Java Agentの検証でOTEL_SERVICE_NAME=trace-checkを指定していた場合、元のサービス名ではなくtrace-checkとして表示される可能性があります。

また、アプリケーションやCollectorの時刻がずれている場合、Traceが想定した時間帯とは異なる場所に記録されることがあります。バックエンドの検索画面で直近5分だけを表示していると、時間がずれたTraceを見落とす可能性があります。

検索可能になるまでの遅延にも注意が必要です。バックエンドによっては、取り込んだデータを索引化する処理が必要であり、送信成功から検索可能になるまでに時間差が生じます。

Trace IDが分かっている場合は、サービス名や操作名などの不要な条件を減らし、そのIDで検索します。Trace IDが分からない場合は、テスト要求を実行した時刻を中心に、検索範囲を広げて確認します。

また、一つのTraceのうち、一部のSpanだけが表示される場合は、すべてのトレースが表示されない問題とは分けて考えます。

たとえば注文サービスのSpanは表示されるのに、決済サービスのSpanが表示されない場合、サービス間でトレースのコンテキストが正しく引き継がれていない可能性があります。

OpenTelemetryでは、HTTP通信などを通じてTrace IDや親子関係の情報を伝搬させます。この情報が正しく伝搬されなければ、下流サービスが別のTraceを開始する場合があります。

その結果、本来一つのTraceとして表示されるはずの処理が、複数の独立したTraceとして保存される可能性があります。

この場合、決済サービスのSpanが失われたとは限りません。別のTrace IDで保存されている可能性もあるため、呼び出し時刻やサービス名を使って検索します。

検索条件を変更するだけでTraceが見つかった場合は、計装や通信の設定が原因だったとは判断できません。どの段階の問題だったかを区別して記録することが重要です。

6. 修正の効果を確かめ、再発時に使える手順を残す

一度に一つの仮説を検証する

原因の候補が見つかったら、設定変更は一つの仮説を検証する単位で行います。複数の設定を同時に変更すると、トレースが表示されるようになっても、どの変更が効果を持ったのか判断しにくくなります。

たとえばExporterのendpoint、サンプラー、Collectorのprocessorを同時に変更した場合、通信先の修正によって解決したのか、サンプリングが無効になったため表示されるようになったのかを区別できません。

そのため、変更前の設定と観測結果を記録し、原因候補を一つずつ検証します。変更後は同じテスト要求を送信し、予想した地点のログやメトリクスが変化したかを確認します。

具体例として、アプリケーション側ではSpanがコンソールに出力されるものの、Collectorでは受信が確認できないケースを考えます。

調査したところ、アプリケーションとCollectorが別々のコンテナで動作しているにもかかわらず、Exporterの送信先に127.0.0.1:4318が指定されていたとします。

この場合、アプリケーションは自身のコンテナ内へ接続しようとしている可能性があります。仮説として送信先の誤りを挙げ、Exporterのendpointを、実際に到達可能なCollectorのサービス名へ変更します。

変更後にCollectorのdebug exporterへ対象Spanが出力されれば、アプリケーションからCollectorまでの経路が改善したと判断できます。

ただし、この時点で調査を終了してはいけません。通常のprocessorと本来のexporterを経由し、バックエンドで同じTrace IDを検索できるところまで確認します。

Collectorへの受信が成功しても、後段で別の設定問題が発生している可能性があるためです。

また、修正後は検証のために変更した設定を元に戻します。たとえばサンプラーをalways_onに変更したまま本番運用を続けると、トレースの保存量が想定以上に増加する可能性があります。

同様に、OTEL_JAVAAGENT_DEBUG=trueやdebug exporterの詳細出力を有効にしたままにすると、ログ量の増加や機密情報の出力につながる場合があります。

検証用のコンソール出力、サンプリング設定、詳細ログ、Collectorの一時的なpipelineなどを確認し、必要なものだけを残します。

修正によって問題が解決した後も、すぐに調査を終了するのではなく、通常のトラフィックでトレースが継続して収集されるかを確認します。一度のテスト要求が成功しただけでは、高負荷時や長時間運用時の問題まで解消したとは限りません。

正常時の証拠と引き継ぎ情報を残す

トレースが届かない問題は、AgentやCollectorのバージョンアップ、ネットワーク構成の変更、認証情報の更新などによって再発する可能性があります。

そのため、原因を修正しただけで終わらせず、再発時に同じ手順で調査できる情報を残すことが重要です。

特に有効なのが、正常時にどのような結果が確認できるかを記録しておくことです。障害発生時のログだけでなく、正常時のログや内部メトリクスを把握していれば、両者を比較して異常な地点を見つけやすくなります。

たとえば代表的なAPIについて、テスト要求の送信方法、期待されるサービス名、通過するCollector、バックエンドの検索先、通常の送信待ち時間を記録します。

また、Collectorの内部メトリクスについても、通常時の受信量や送信量、送信待ちキューの使用状況を把握しておくと、異常時の判断材料になります。

調査結果は、次のような項目で整理すると引き継ぎやすくなります。

記録項目内容の例
発生環境検証環境、注文照会API
発生事象APIは正常終了するがTraceが検索できない
再現方法指定した注文照会APIへGETリクエストを送信
確認できた地点Java Agentのコンソール出力までは確認
確認できなかった地点Collectorの受信ログ、内部メトリクス
原因Exporterの接続先に誤ったホストを指定
修正内容正しいCollectorのサービス名へ変更
修正後の結果Collector受信とバックエンド検索を確認

このように整理しておけば、同じ問題が発生した際に、最初からすべての設定を確認し直す必要がなくなります。

また、関係者へ調査を依頼する場合も、確認できた事実を具体的に伝えることが重要です。

単に「トレースが表示されません」と伝えるだけでは、アプリケーション、Collector、ネットワーク、バックエンドのどこを確認すべきか分かりません。

一方、「検証環境の注文照会APIを実行し、Java Agentのコンソール出力は確認できたものの、Collectorの受信ログと内部メトリクスでは対象Spanを確認できていない」と伝えれば、調査対象を通信経路やreceiver周辺に絞りやすくなります。

継続的な監視では、Collectorの送信失敗数、送信待ちキューの増加、プロセスの再起動などを監視対象にします。業務APIの応答が正常でも、トレースの収集経路だけが停止する可能性があるためです。

また、サンプリングによって通常時のトレース数が変動する環境では、単に収集件数が少ないことだけを異常と判断しないようにします。設定した収集方針と通常のトラフィック量を踏まえ、異常な欠落を検出できる監視条件を設計します。

復旧後は、代表的なテスト要求に加え、通常のトラフィックでも受信・送信が継続していることを確認します。バックエンドでTrace IDを検索できることまで確認し、設定変更の理由と結果を記録して、対応を完了とします。

まとめ

OpenTelemetryでトレースが見つからない場合は、画面に表示されないという結果だけで原因を判断せず、アプリケーションからバックエンドまでの経路を段階的に確認することが重要です。

まず再現可能なテスト要求を固定し、Java AgentによるSpanの生成、ExporterからのOTLP送信、Collectorでの受信・加工・送信、バックエンドでの保存・検索を順に調べます。

Java Agentのコンソール出力を利用すれば、ネットワークを経由する前の計装状況を確認できます。また、Collectorのdebug exporterや内部メトリクスは、データがどの段階まで到達しているかを判断する手掛かりになります。

一方、サンプリングによる意図的な除外、batch処理やテールサンプリングによる待機、検索条件の取り違えなど、通信障害以外の理由でTraceが見つからない場合もあります。データが存在しないことと、まだ表示されていないことを区別する必要があります。

原因を修正する際は、一度に複数の設定を変更せず、一つの仮説ごとに同じテスト要求で検証します。修正後は本来のpipelineを通してバックエンドまで到達することを確認し、検証用の設定を元に戻します。

正常時のデータ経路や確認手順を記録しておくことで、同様の問題が発生した場合にも効率的に切り分けられます。各段階に確認できる証拠を残し、トレースの収集経路そのものを継続的に監視することが大切です。

参考リンク