Troubleshoot OpenTelemetry Collector Issues
20 minutes前のセクションでは、debug エクスポーターをコレクターの設定に追加し、 トレースとログのパイプラインの一部にしました。期待通りに、debug 出力が エージェントコレクターのログに書き込まれているのが確認できます。
しかし、トレースが o11y cloud に送信されなくなっています。なぜなのかを把握して修正しましょう。
コレクター設定を確認する
values.yaml
ファイルを通じてコレクター設定が変更された場合は、
config map を確認してコレクターに実際に適用された設定を確認することが役立ちます:
kubectl describe cm splunk-otel-collector-otel-agent
エージェントコレクター設定のログとトレースのパイプラインを確認しましょう。次のようになっているはずです:
pipelines:
logs:
exporters:
- debug
processors:
- memory_limiter
- k8sattributes
- filter/logs
- batch
- resourcedetection
- resource
- resource/logs
- resource/add_environment
receivers:
- filelog
- fluentforward
- otlp
...
traces:
exporters:
- debug
processors:
- memory_limiter
- k8sattributes
- batch
- resourcedetection
- resource
- resource/add_environment
receivers:
- otlp
- jaeger
- smartagent/signalfx-forwarder
- zipkin
問題がわかりますか?debug エクスポーターのみがトレースとログのパイプラインに含まれています。
以前のトレースパイプライン設定にあったotlphttp
とsignalfx
エクスポーターがなくなっています。
これが、もう o11y cloud でトレースが見えなくなった理由です。ログパイプラインについても、splunk_hec/platform_logs
エクスポーターが削除されています。
どのような特定のエクスポーターが以前含まれていたかをどのように知ったか?それを見つけるには、 以前のカスタマイズを元に戻してから、config map を確認して トレースパイプラインに元々何が含まれていたかを見ることもできました。あるいは、 splunk-otel-collector-chart の GitHub リポジトリ の例を参照することもでき、これにより Helm チャートで使用されるデフォルトのエージェント設定が分かります。
これらのエクスポーターはどのように削除されたのか?
values.yaml
ファイルに追加したカスタマイズを確認しましょう:
logsEngine: otel
splunkObservability:
infrastructureMonitoringEventsEnabled: true
agent:
config:
receivers: ...
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
exporters:
- debug
logs:
exporters:
- debug
helm upgrade
を使ってコレクターにvalues.yaml
ファイルを適用したとき、
カスタム設定は以前のコレクター設定とマージされました。
これが発生すると、リストを含むyaml
設定のセクション、
例えばパイプラインセクションのエクスポーターのリストは、values.yaml
ファイルに
含めたもの(debug エクスポーターのみ)で置き換えられます。
問題を修正しましょう
既存のパイプラインをカスタマイズする場合、設定のその部分を完全に再定義する必要があります。
したがって、values.yaml
ファイルを次のように更新する必要があります:
logsEngine: otel
splunkObservability:
infrastructureMonitoringEventsEnabled: true
agent:
config:
receivers: ...
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
exporters:
- otlphttp
- signalfx
- debug
logs:
exporters:
- splunk_hec/platform_logs
- debug
変更を適用しましょう:
helm upgrade splunk-otel-collector \
--set="splunkObservability.realm=$REALM" \
--set="splunkObservability.accessToken=$ACCESS_TOKEN" \
--set="clusterName=$INSTANCE-cluster" \
--set="environment=otel-$INSTANCE" \
--set="splunkPlatform.token=$HEC_TOKEN" \
--set="splunkPlatform.endpoint=$HEC_URL" \
--set="splunkPlatform.index=splunk4rookies-workshop" \
-f values.yaml \
splunk-otel-collector-chart/splunk-otel-collector
それからエージェント config map を確認します:
kubectl describe cm splunk-otel-collector-otel-agent
今度は、ログとトレースの両方について完全に定義されたエクスポーターパイプラインが表示されるはずです:
pipelines:
logs:
exporters:
- splunk_hec/platform_logs
- debug
processors:
...
traces:
exporters:
- otlphttp
- signalfx
- debug
processors:
...
ログ出力の確認
Splunk Distribution of OpenTelemetry .NETは、ログに使用するアプリケーション (サンプルアプリでも使用している)から、トレースコンテキストで強化されたログを自動的にエクスポートします。
アプリケーションログはトレースメタデータで強化され、その後 OpenTelemetry Collector のローカルインスタンスに OTLP 形式でエクスポートされます。
debug エクスポーターによってキャプチャされたログを詳しく見て、それが発生しているかを確認しましょう。 コレクターログを tail するには、次のコマンドを使用できます:
kubectl logs -l component=otel-collector-agent -f
ログを tail したら、curl を使ってさらにトラフィックを生成できます。そうすると 次のようなものが表示されるはずです:
2024-12-20T21:56:30.858Z info Logs {"kind": "exporter", "data_type": "logs", "name": "debug", "resource logs": 1, "log records": 1}
2024-12-20T21:56:30.858Z info ResourceLog #0
Resource SchemaURL: https://opentelemetry.io/schemas/1.6.1
Resource attributes:
-> splunk.distro.version: Str(1.8.0)
-> telemetry.distro.name: Str(splunk-otel-dotnet)
-> telemetry.distro.version: Str(1.8.0)
-> os.type: Str(linux)
-> os.description: Str(Debian GNU/Linux 12 (bookworm))
-> os.build_id: Str(6.8.0-1021-aws)
-> os.name: Str(Debian GNU/Linux)
-> os.version: Str(12)
-> host.name: Str(derek-1)
-> process.owner: Str(app)
-> process.pid: Int(1)
-> process.runtime.description: Str(.NET 8.0.11)
-> process.runtime.name: Str(.NET)
-> process.runtime.version: Str(8.0.11)
-> container.id: Str(5bee5b8f56f4b29f230ffdd183d0367c050872fefd9049822c1ab2aa662ba242)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.language: Str(dotnet)
-> telemetry.sdk.version: Str(1.9.0)
-> service.name: Str(helloworld)
-> deployment.environment: Str(otel-derek-1)
-> k8s.node.name: Str(derek-1)
-> k8s.cluster.name: Str(derek-1-cluster)
ScopeLogs #0
ScopeLogs SchemaURL:
InstrumentationScope HelloWorldController
LogRecord #0
ObservedTimestamp: 2024-12-20 21:56:28.486804 +0000 UTC
Timestamp: 2024-12-20 21:56:28.486804 +0000 UTC
SeverityText: Information
SeverityNumber: Info(9)
Body: Str(/hello endpoint invoked by {name})
Attributes:
-> name: Str(Kubernetes)
Trace ID: 78db97a12b942c0252d7438d6b045447
Span ID: 5e9158aa42f96db3
Flags: 1
{"kind": "exporter", "data_type": "logs", "name": "debug"}
この例では、Trace ID と Span ID が OpenTelemetry .NET 計装によってログ出力に自動的に書き込まれていることがわかります。これにより、 Splunk Observability Cloud でログとトレースを関連付けることができます。
ただし、Helm を使って K8s クラスターに OpenTelemetry collector をデプロイし、 ログ収集オプションを含める場合、OpenTelemetry collector は File Log receiver を使用して コンテナーログを自動的にキャプチャすることを覚えておいてください。
これにより、アプリケーションの重複ログがキャプチャされることになります。例えば、次のスクリーンショットでは サービスへの各リクエストに対して 2 つのログエントリーが表示されています:
これをどのように回避しますか?
K8s での重複ログの回避
重複ログをキャプチャしないようにするには、OTEL_LOGS_EXPORTER
環境変数をnone
に設定して、
Splunk Distribution of OpenTelemetry .NET が OTLP を使用してコレクターにログをエクスポートしないようにできます。
これは、deployment.yaml
ファイルにOTEL_LOGS_EXPORTER
環境変数を追加することで実行できます:
env:
- name: PORT
value: "8080"
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://$(NODE_IP):4318"
- name: OTEL_SERVICE_NAME
value: "helloworld"
- name: OTEL_RESOURCE_ATTRIBUTES
value: "deployment.environment=otel-$INSTANCE"
- name: OTEL_LOGS_EXPORTER
value: "none"
それから次を実行します:
# update the deployment
kubectl apply -f deployment.yaml
OTEL_LOGS_EXPORTER
環境変数をnone
に設定するのは簡単です。しかし、Trace ID と
Span ID はアプリケーションによって生成された stdout ログに書き込まれないため、
ログとトレースを関連付けることができなくなります。
これを解決するには、
/home/splunk/workshop/docker-k8s-otel/helloworld/SplunkTelemetryConfigurator.cs
で定義されている例のような、カスタムロガーを定義する必要があります。
次のようにProgram.cs
ファイルを更新することで、これをアプリケーションに含めることができます:
using SplunkTelemetry;
using Microsoft.Extensions.Logging.Console;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
SplunkTelemetryConfigurator.ConfigureLogger(builder.Logging);
var app = builder.Build();
app.MapControllers();
app.Run();
その後、カスタムログ設定を含む新しい Docker イメージをビルドします:
cd /home/splunk/workshop/docker-k8s-otel/helloworld
docker build -t helloworld:1.3 .
それから更新されたイメージを Kubernetes にインポートします:
cd /home/splunk
# Export the image from docker
docker save --output helloworld.tar helloworld:1.3
# Import the image into k3s
sudo k3s ctr images import helloworld.tar
最後に、deployment.yaml
ファイルを更新してコンテナーイメージの 1.3 バージョンを使用する必要があります:
spec:
containers:
- name: helloworld
image: docker.io/library/helloworld:1.3
それから変更を適用します:
# update the deployment
kubectl apply -f deployment.yaml
これで重複したログエントリーが排除されたことがわかります。そして 残りのログエントリーは JSON としてフォーマットされ、span と trace ID が含まれています: