OpenTelemetry OpenTelemetry

Collector と SDK のトラブルシューティング

テレメトリが届かないときの体系的なチェックリスト:debug exporter、ヘルスチェック、内部メトリクス、よくある間違い。

12 min learn.level.中級

「データが見えない」は、OpenTelemetry で最も一般的な問題であり、その原因はほとんどの場合、設定ミスの短いリストのうちの 1 つです。アプリケーションから外側へ、一度に 1 ホップずつ作業し、次に進む前に、各ホップを証明してください。

アプリの SDK ──▶ Collector の receiver ──▶ processors ──▶ exporter ──▶ バックエンド
     1                 2                      3             4            5

ステップ 0:設定を検証する

otelcol-contrib validate --config=config.yaml

これは、YAML のエラー、不明なコンポーネント名、不正なオプション名、定義されていないコンポーネントを参照するパイプラインを検出します。ディストリビューションに合うバイナリ名(otelcol、otelcol-contrib、otelcol-k8s)を使ってください。コンテナでは、デプロイと同じイメージとマウントした設定で実行します。

ステップ 1:SDK は送信しているか

SDK の診断とコンソール exporter を有効にして、「アプリが何も生成しなかった」と「生成したが届かなかった」を切り分けます。

export OTEL_LOG_LEVEL=debug
export OTEL_TRACES_EXPORTER=console   # または "logging"。言語によって異なる

一般的な原因を確認します。

  • エンドポイントとプロトコルが一致していない。 OTEL_EXPORTER_OTLP_PROTOCOL はポートと一致する必要があります。grpc は 4317、http/protobuf は 4318 です。HTTP を gRPC のポートに、あるいはその逆に送ると、接続やパースの問題のように見えるエラーで失敗します。
  • HTTP で間違ったパス。 OTEL_EXPORTER_OTLP_ENDPOINT はベースの URL で、SDK が /v1/traces を追加します。OTEL_EXPORTER_OTLP_TRACES_ENDPOINT のようなシグナル固有の変数は、与えられたとおりに使われるため、完全なパスを含める必要があります。
  • コンテナ内の localhost。 アプリの localhost は、アプリ自身です。Collector の Service またはコンテナ名を使います。
  • SDK が無効、または exporter が none。 OTEL_SDK_DISABLED=true や OTEL_TRACES_EXPORTER=none を探します。
  • service.name がない。 データは受け付けられますが unknown_service として表示されるため、データがないように見えます。OTEL_SERVICE_NAME を設定します。
  • 短命なプロセスが、エクスポートの前に終了する。 バッチの exporter は定期的に送信するため、終了前に SDK のシャットダウンやフラッシュを呼び出します。

ステップ 2:receiver に到達できるか

curl -i http://collector:4318/v1/traces \
  -H 'Content-Type: application/json' -d '{}'

HTTP 200 のレスポンス(空の JSON ボディで構いません)は、HTTP の receiver に到達できることを示します。gRPC では、grpcurl のようなツールか、TCP のチェック(nc -zv collector 4317)で、ポートが開いていることを証明します。そうでない場合:

  • receiver が localhost にバインドされている可能性があります。endpoint: 0.0.0.0:4317 を明示的に設定します。
  • Kubernetes の Service がポートを公開していないか、Pod の containerPort がありません。
  • NetworkPolicy、ファイアウォール、サービスメッシュが、トラフィックをブロックしている可能性があります。

ステップ 3:パイプラインは接続されているか

これは最もよくある Collector の間違いです。定義されているが使われていないコンポーネントです。exporters.otlp/tempo を定義しても、service.pipelines.<signal>.exporters に現れるまで、何も起こりません。receiver、processor、extension、connector も同様です。

確認すること:

  • パイプライン内のコンポーネントの名前が、サフィックスを含め、定義と正確に一致していること(otlpではなく、otlp/tempo)。
  • シグナルのタイプが一致していること:traces のパイプラインは、トレースをサポートしない receiver や exporter を使えません。
  • extension が service.extensions に列挙されていること。
  • Helm の values では、リストが置き換えられることを思い出してください。部分的に再定義したパイプラインは、デフォルトのコンポーネントを失っている可能性があります。

ステップ 4:Collector の内部でデータを見る

パイプラインに debug exporter を追加します。

exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [debug, otlp/tempo]

Collector のログを読みます。そこにスパンが見えれば、receiver と processor が機能していることが分かるので、問題は後段にあります。何も見えない場合は、データがパイプラインに届かなかったか、processor が破棄したかです(filter の processor や tail サンプラーが、よくある容疑者です)。完了したら、debug を削除するか、詳細度を下げてください。すべての項目をログに記録するからです。

ステップ 5:Collector 自身のシグナルを使う

ヘルスチェック:

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
service:
  extensions: [health_check]

curl http://collector:13133/ がステータスを返します。Kubernetes の liveness と readiness の probe に使います。

内部メトリクスは、デフォルトでポート 8888 で提供されます(お使いのバージョンの service.telemetry.metrics を確認)。

curl -s http://collector:8888/metrics | grep -E 'otelcol_(receiver|processor|exporter)_'

ファネルのように読みます。

メトリクスのファミリー意味
otelcol_receiver_accepted_*正常に受信された項目
otelcol_receiver_refused_*拒否された項目。多くは memory_limiter による
otelcol_processor_dropped_*processor によって破棄された項目
otelcol_exporter_sent_*バックエンドに配信された項目
otelcol_exporter_send_failed_*バックエンドが拒否した、または到達できなかった項目
otelcol_exporter_queue_size と _capacityキューの深さと、その上限

accepted のカウントが増えているのに sent が横ばいなら、問題は exporter にあります。refused のカウントは、メモリ制限を指しています。メトリクス名はリリース間で調整されているため、お使いのバージョンの Collector の内部テレメトリのドキュメントを確認してください。

zPages は、パイプラインと最近のトレースのライブビューを提供します。

extensions:
  zpages:
    endpoint: localhost:55679

/debug/tracez と /debug/pipelinez を開きます(クラスターでは kubectl port-forward 経由)。localhost にバインドしたままにしてください。

ステップ 6:バックエンドはそれを受け入れているか

Collector のログで、exporter のエラーを確認します。

  • connection refused または deadline exceeded:間違ったエンドポイントやポート、あるいはネットワークのブロック。
  • certificate signed by unknown authority:tls.ca_file を追加するか、エンドポイントが正しいホスト名を使うように修正します。
  • 401 または 403:トークンやヘッダーがないか、間違っています。未設定の ${env:VAR} は空の値になるため、変数が Pod で設定されていることを確認します(kubectl exec ... -- env)。
  • 415 やパースのエラー:プロトコルの不一致。たとえば、otlp(gRPC)を HTTP のポートに向けている。
  • HTTP での 404:バックエンドが期待するベースのパスを確認します(Loki は /otlp、Prometheus は /api/v1/otlp)。
  • Prometheus が OTLP を拒否する:その OTLP receiver の feature flag が有効になっていません。

自動計装のチェック

Operator ベースの注入では、Instrumentation が Pod の起動前に存在したこと、アノテーションが Pod テンプレートにあること、アプリケーションの Pod に opentelemetry-auto-instrumentation という init コンテナがあることを確認します。リソースを作成または変更した後は、ワークロードを再起動します。エージェントベースの構成では、エージェントのフラグや環境変数が実際に適用されていることを確認します(-javaagent:、opentelemetry-instrument、--require)。

クイックリファレンス

症状最初に確認すること
Collector のログに何もないSDK のエンドポイント、プロトコル、ポート。コンテナ内の localhost
Collector はデータを受信するが、バックエンドは受信しないパイプライン内の exporter、エンドポイント、認証、プロトコル
Collector が起動しないvalidate の出力。イメージにないコンポーネント
データが unknown_service として表示されるOTEL_SERVICE_NAME を設定する
メモリの増加や再起動memory_limiter を最初に、キューのサイズ、リソースの制限
サンプリング後の部分的なトレース1 つのトレースは 1 つの Collector に届く必要がある(ロードバランシングの層)
一部のデータが断続的に欠落するキューがいっぱい、またはリトライの上限に達した。send_failed とキューのメトリクスを確認

一度に 1 ホップずつ修正し、作業中は debug exporter を手元に置き、次のインシデントが証拠から始まるように、Collector の内部メトリクスをダッシュボードに載せてください。

人気のガイド