Splunk4Ninjas Workshops

  • Java アプリケーション向けの Splunk 自動ディスカバリーおよび設定機能の活用方法を学びます。これらのワークショップでは、ゼロコード計装を使用して、モノリスおよび Kubernetes デプロイメント全体でメトリクス、トレース、ログを即座に生成し、包括的なオブザーバビリティを実現する方法をデモンストレーションします。
  • OpenTelemetry Collector の基本概念 OpenTelemetry Collector の概念と、Splunk Observability Cloud へデータを送信する方法を学びます。 Advanced OpenTelemetry Collector OpenTelemetry Collector の設定をゼロから行う練習を行い、いくつかの高度な設定シナリオを体験します。
  • ユーザーフロー、ビジネストランザクション、API 全体のパフォーマンス問題をプロアクティブに検出・修正し、より優れたデジタルエクスペリエンスを提供します。
  • このワークショップでは、AWS Lambdaで実行される小規模なサーバーレスアプリケーションの分散トレースを構築し、AWS Kinesisを介してメッセージをproduceおよびconsumeする方法を学びます
  • このワークショップでは、これらの概念を説明するためにシンプルな.NETアプリケーションを使用します。さあ、始めましょう!ワークショップの終わりまでに、OpenTelemetryを使用した.NETアプリケーションの計装の実践経験を積み、そのアプリケーションのDocker化およびKubernetesへのデプロイを行います。また、Helmを使用したOpenTelemetryコレクターのデプロイ、コレクター設定のカスタマイズ、コレクター設定の問題のトラブルシューティングの経験も得られます。
Last Modified 2025/09/29

Splunk4Ninjas Workshopsのサブセクション

自動ディスカバリーワークショップ

  • Spring PetClinic サンプルアプリケーションを使用して、Java アプリケーション向けの Splunk Observability Cloud の自動ディスカバリーおよび設定機能をデモンストレーションするハンズオンワークショップです。
  • Kubernetes で実行される Java ベースのアプリケーション向けの自動ディスカバリーおよび設定を有効にする方法を学びます。リアルタイムモニタリングを体験し、エンドツーエンドの可視性でアプリケーションの動作を最大限に活用しましょう。
Last Modified 2026/01/05

自動ディスカバリーワークショップのサブセクション

PetClinic モノリスワークショップ

30 minutes   Author Robert Castley

このワークショップの目的は、Splunk Observability Cloud プラットフォームの以下のコンポーネントを設定するための基本的な手順を説明することです:

  • Splunk Infrastructure Monitoring (IM)
  • Splunk Automatic Discovery for Java (APM)
    • Database Query Performance
    • AlwaysOn Profiling
  • Splunk Real User Monitoring (RUM)
  • RUM から APM への相関
  • Splunk Log Observer (LO)

また、サンプル Java アプリケーション(Spring PetClinic)のクローン(ダウンロード)方法、およびアプリケーションのコンパイル、パッケージ化、実行方法についても説明します。

アプリケーションが起動して実行されると、Splunk APM 製品で使用される Java 2.x 向けの自動ディスカバリーおよび設定機能により、メトリクス、トレース、ログが即座に表示されるようになります。

その後、Splunk OpenTelemetry Javascript Libraries (RUM) を使用して PetClinic のエンドユーザーインターフェース(アプリケーションがレンダリングする HTML ページ)を計装します。これにより、エンドユーザーが実行するすべてのクリックやページ読み込みに対して RUM トレースが生成されます。

最後に、PetClinic アプリケーションログへのトレースメタデータの自動インジェクションによって生成されたログを確認します。

前提条件
  • ポート 2222 へのアウトバウンド SSH アクセス
  • ポート 8083 へのアウトバウンド HTTP アクセス
  • bash シェルおよび vi/vim エディタの基本的な知識

PetClinic Exercise PetClinic Exercise

Last Modified 2026/01/05

PetClinic モノリスワークショップのサブセクション

OpenTelemetry Collector のインストール

Splunk OpenTelemetry Collector は、インフラストラクチャとアプリケーションの計装における中核コンポーネントです。その役割は以下のデータを収集して送信することです:

  • インフラストラクチャメトリクス(ディスク、CPU、メモリなど)
  • Application Performance Monitoring (APM) トレース
  • プロファイリングデータ
  • ホストおよびアプリケーションのログ
既存の OpenTelemetry Collector の削除

Splunk IM ワークショップを完了している場合は、続行する前に Kubernetes で実行中の Collector を削除してください。以下のコマンドを実行して削除できます:

helm delete splunk-otel-collector

EC2 インスタンスには、古いバージョンの Collector がすでにインストールされている場合があります。Collector をアンインストールするには、以下のコマンドを実行してください:

curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh
sudo sh /tmp/splunk-otel-collector.sh --uninstall

インスタンスが正しく設定されていることを確認するために、このワークショップに必要な環境変数が正しく設定されているか確認する必要があります。ターミナルで以下のコマンドを実行してください:

. ~/workshop/petclinic/scripts/check_env.sh

出力で、以下のすべての環境変数が存在し、値が設定されていることを確認してください。不足している場合は、インストラクターに連絡してください:

ACCESS_TOKEN
REALM
RUM_TOKEN
HEC_TOKEN
HEC_URL
INSTANCE

これで Collector のインストールに進むことができます。インストールスクリプトには、いくつかの追加パラメータが渡されます:

  • --with-instrumentation - Splunk ディストリビューションの OpenTelemetry Java からエージェントをインストールします。これにより、PetClinic Java アプリケーションの起動時に自動的にロードされます。設定は不要です!
  • --deployment-environment - リソース属性 deployment.environment を指定された値に設定します。これは UI でビューをフィルタリングするために使用されます。
  • --enable-profiler - Java アプリケーションのプロファイラを有効にします。これによりアプリケーションの CPU プロファイルが生成されます。
  • --enable-profiler-memory - Java アプリケーションのプロファイラを有効にします。これによりアプリケーションのメモリプロファイルが生成されます。
  • --enable-metrics - Micrometer メトリクスのエクスポートを有効にします
  • --hec-token - Collector が使用する HEC トークンを設定します
  • --hec-url - Collector が使用する HEC URL を設定します
curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh && \
sudo sh /tmp/splunk-otel-collector.sh --realm $REALM -- $ACCESS_TOKEN --mode agent --without-fluentd --with-instrumentation --deployment-environment $INSTANCE-petclinic --enable-profiler --enable-profiler-memory --enable-metrics --hec-token $HEC_TOKEN --hec-url $HEC_URL

次に、Collector にパッチを適用して、AWS インスタンス ID ではなくインスタンスのホスト名を公開するようにします。これにより、UI でのデータのフィルタリングが容易になります:

sudo sed -i 's/gcp, ecs, ec2, azure, system/system, gcp, ecs, ec2, azure/g' /etc/otel/collector/agent_config.yaml

agent_config.yaml にパッチを適用したら、Collector を再起動する必要があります:

sudo systemctl restart splunk-otel-collector

インストールが完了したら、Hosts with agent installed ダッシュボードに移動して、ホストからのデータを確認できます。Dashboards → Hosts with agent installed の順に移動してください。

ダッシュボードフィルタを使用して host.name を選択し、ワークショップインスタンスのホスト名を入力または選択してください(これはターミナルセッションのコマンドプロンプトから取得できます)。ホストのデータが流れていることを確認したら、APM コンポーネントの作業を開始する準備が整いました。

Last Modified 2025/12/05

Spring PetClinic アプリケーションのビルド

APM をセットアップするために最初に必要なのは…そう、アプリケーションです。この演習では、Spring PetClinic アプリケーションを使用します。これは、Spring フレームワーク(Springboot)で構築された非常に人気のあるサンプル Java アプリケーションです。

まず、PetClinic の GitHub リポジトリをクローンし、その後アプリケーションのコンパイル、ビルド、パッケージ化、テストを行います:

git clone https://github.com/spring-projects/spring-petclinic

spring-petclinic ディレクトリに移動します:

cd spring-petclinic
git checkout b26f235250627a235a2974a22f2317dbef27338d

Docker を使用して、PetClinic が使用する MySQL データベースを起動します:

docker run -d -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 docker.io/biarms/mysql:5.7

次に、PetClinic アプリケーションにシンプルなトラフィックを生成する Locust を実行する別のコンテナを起動します。Locust は、Web アプリケーションにトラフィックを生成するために使用できるシンプルな負荷テストツールです。

docker run --network="host" -d -p 8090:8090 -v ~/workshop/petclinic:/mnt/locust docker.io/locustio/locust -f /mnt/locust/locustfile.py --headless -u 1 -r 1 -H http://127.0.0.1:8083

次に、maven を使用して PetClinic をコンパイル、ビルド、パッケージ化します:

./mvnw package -Dmaven.test.skip=true
情報

初回実行時は数分かかり、アプリケーションをコンパイルする前に多くの依存関係をダウンロードします。以降のビルドはより高速になります。

ビルドが完了したら、実行しているインスタンスのパブリック IP アドレスを取得する必要があります。以下のコマンドを実行して取得できます:

curl http://ifconfig.me

IP アドレスが返されます。アプリケーションが実行されていることを確認するために必要になるので、この IP アドレスをメモしておいてください。

Last Modified 2025/12/05

3. Real User Monitoring

Real User Monitoring (RUM) の計装では、ページに OpenTelemetry Javascript スニペット https://github.com/signalfx/splunk-otel-js-web を追加します。ウィザードを使用して Data Management → Add Integration → RUM Instrumentation → Browser Instrumentation の順に進みます。

インストラクターがドロップダウンから使用するトークンを指示します。Next をクリックしてください。以下の形式で App nameEnvironment を入力します:

  • <INSTANCE>-petclinic-service - <INSTANCE> を先ほどメモした値に置き換えてください。
  • <INSTANCE>-petclinic-env - <INSTANCE> を先ほどメモした値に置き換えてください。

ウィザードは、ページの <head> セクションの先頭に配置する必要がある HTML コードスニペットを表示します。以下は例です(このスニペットは使用せず、ウィザードが生成したものを使用してください):

/*

IMPORTANT: Replace the <version> placeholder in the src URL with a
version from https://github.com/signalfx/splunk-otel-js-web/releases

*/
<script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
<script>
    SplunkRum.init({
        realm: "eu0",
        rumAccessToken: "<redacted>",
        applicationName: "petclinic-1be0-petclinic-service",
        deploymentEnvironment: "petclinic-1be0-petclinic-env"
    });
</script>

Spring PetClinic アプリケーションは、アプリケーションのすべてのページで再利用される単一の HTML ページを「レイアウト」ページとして使用しています。Splunk RUM 計装ライブラリを挿入するには、すべてのページで自動的に読み込まれるため、この場所が最適です。

それでは、レイアウトページを編集しましょう:

vi src/main/resources/templates/fragments/layout.html

次に、上記で生成したスニペットをページの <head> セクションに挿入します。コメントは含めず、ソース URL の <version>latest に置き換えてください:

<!doctype html>
<html th:fragment="layout (template, menu)">

<head>
<script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
<script>
    SplunkRum.init({
        realm: "eu0",
        rumAccessToken: "<redacted>",
        applicationName: "petclinic-1be0-petclinic-service",
        deploymentEnvironment: "petclinic-1be0-petclinic-env"
    });
</script>
...

コード変更が完了したら、アプリケーションを再ビルドして再度実行する必要があります。maven コマンドを実行して PetClinic をコンパイル/ビルド/パッケージ化します:

./mvnw package -Dmaven.test.skip=true
java \
-Dserver.port=8083 \
-Dotel.service.name=$INSTANCE-petclinic-service \
-Dotel.resource.attributes=deployment.environment=$INSTANCE-petclinic-env,version=0.314 \
-jar target/spring-petclinic-*.jar --spring.profiles.active=mysql

次に、ブラウザを使用してアプリケーション http://<IP_ADDRESS>:8083 にアクセスし、実際のユーザートラフィックを生成します。

RUM で、上記の RUM スニペットで定義された環境にフィルタリングし、ダッシュボードをクリックして開きます。

RUM トレースをドリルダウンすると、スパン内に APM へのリンクが表示されます。トレース ID をクリックすると、現在の RUM トレースに対応する APM トレースに移動します。

Last Modified 2025/12/05

Java 向け自動ディスカバリーおよび設定

以下のコマンドでアプリケーションを起動できます。mysql プロファイルをアプリケーションに渡していることに注目してください。これにより、先ほど起動した MySQL データベースを使用するようアプリケーションに指示します。また、otel.service.nameotel.resource.attributes をインスタンス名を使用した論理名に設定しています。これらは UI でのフィルタリングにも使用されます:

java \
-Dserver.port=8083 \
-Dotel.service.name=$INSTANCE-petclinic-service \
-Dotel.resource.attributes=deployment.environment=$INSTANCE-petclinic-env \
-jar target/spring-petclinic-*.jar --spring.profiles.active=mysql

http://<IP_ADDRESS>:8083<IP_ADDRESS> を先ほど取得した IP アドレスに置き換えてください)にアクセスして、アプリケーションが実行されていることを確認できます。

Collector をインストールした際、AlwaysOn ProfilingMetrics を有効にするように設定しました。これにより、Collector はアプリケーションの CPU およびメモリプロファイルを自動的に生成し、Splunk Observability Cloud に送信します。

PetClinic アプリケーションを起動すると、Collector がアプリケーションを自動的に検出し、トレースとプロファイリングのために計装するのが確認できます。

Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
[otel.javaagent 2024-08-20 11:35:58:970 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: splunk-2.6.0-otel-2.6.0
[otel.javaagent 2024-08-20 11:35:59:730 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-08-20 11:35:59:730 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - Profiler configuration:
[otel.javaagent 2024-08-20 11:35:59:730 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                  splunk.profiler.enabled : true
[otel.javaagent 2024-08-20 11:35:59:731 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                splunk.profiler.directory : /tmp
[otel.javaagent 2024-08-20 11:35:59:731 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -       splunk.profiler.recording.duration : 20s
[otel.javaagent 2024-08-20 11:35:59:731 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -               splunk.profiler.keep-files : false
[otel.javaagent 2024-08-20 11:35:59:732 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -            splunk.profiler.logs-endpoint : null
[otel.javaagent 2024-08-20 11:35:59:732 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -              otel.exporter.otlp.endpoint : null
[otel.javaagent 2024-08-20 11:35:59:732 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -           splunk.profiler.memory.enabled : true
[otel.javaagent 2024-08-20 11:35:59:732 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -        splunk.profiler.memory.event.rate : 150/s
[otel.javaagent 2024-08-20 11:35:59:732 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.call.stack.interval : PT10S
[otel.javaagent 2024-08-20 11:35:59:733 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -  splunk.profiler.include.internal.stacks : false
[otel.javaagent 2024-08-20 11:35:59:733 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.tracing.stacks.only : false
[otel.javaagent 2024-08-20 11:35:59:733 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-08-20 11:35:59:733 +0000] [main] INFO com.splunk.opentelemetry.profiler.JfrActivator - Profiler is active.

Splunk APM UI にアクセスして、アプリケーションコンポーネント、トレース、プロファイリング、DB Query パフォーマンス、メトリクスを確認できます。左側のメニューから APM をクリックし、Environment ドロップダウンをクリックして、ご自身の環境(例:<INSTANCE>-petclinic<INSTANCE> は先ほどメモした値に置き換えてください)を選択します。

検証が完了したら、Ctrl-c を押してアプリケーションを停止できます。

リソース属性は、報告されるすべてのスパンに追加できます。例えば version=0.314 のように指定します。カンマ区切りのリソース属性リストも定義できます(例:key1=val1,key2=val2)。

新しいリソース属性を使用して PetClinic を再度起動しましょう。実行コマンドにリソース属性を追加すると、Collector のインストール時に定義された内容が上書きされることに注意してください。新しいリソース属性 version=0.314 を追加しましょう:

java \
-Dserver.port=8083 \
-Dotel.service.name=$INSTANCE-petclinic-service \
-Dotel.resource.attributes=deployment.environment=$INSTANCE-petclinic-env,version=0.314 \
-jar target/spring-petclinic-*.jar --spring.profiles.active=mysql

Splunk APM UI に戻り、最近のトレースをドリルダウンすると、スパン内に新しい version 属性が表示されます。

Last Modified 2025/12/05

4. Log Observer

Splunk Log Observer コンポーネントでは、Splunk OpenTelemetry Collector が Spring PetClinic アプリケーションからログを自動的に収集し、OTLP エクスポーターを使用して Splunk Observability Cloud に送信します。その際、ログイベントに trace_idspan_id、トレースフラグを付与します。

Log Observer は、アプリケーションとインフラストラクチャからのログをリアルタイムで表示します。ログの検索、フィルタリング、分析を行って、問題のトラブルシューティングや環境の監視が可能です。

PetClinic Web アプリケーションに戻り、Error リンクを数回クリックしてください。これにより、PetClinic アプリケーションログにいくつかのログメッセージが生成されます。

PetClinic Error PetClinic Error

左側のメニューから Log Observer をクリックし、Indexsplunk4rookies-workshop に設定されていることを確認してください。

次に、Add Filter をクリックし、フィールド service.name を検索して、値 <INSTANCE>-petclinic-service を選択し、=(include)をクリックします。これで、PetClinic アプリケーションからのログメッセージのみが表示されるはずです。

PetClinic アプリケーションの Error リンクをクリックして生成されたログエントリの1つを選択してください。ログメッセージと、ログメッセージに自動的にインジェクションされたトレースメタデータが表示されます。また、APM と Infrastructure の Related Content が利用可能であることにも注目してください。

Log Observer Log Observer

これでワークショップは終了です。多くの内容をカバーしました。この時点で、メトリクス、トレース(APM と RUM)、ログ、データベースクエリパフォーマンス、コードプロファイリングが Splunk Observability Cloud に報告されているはずです。しかも、PetClinic アプリケーションのコードを変更することなく実現できました(RUM を除く)。

おめでとうございます!

Last Modified 2025/12/05

Kubernetes 上の Spring PetClinic SpringBoot ベースのマイクロサービス

90 minutes   Author Pieter Hagen

このワークショップの目的は、Java 向けの Splunk 自動ディスカバリーおよび設定機能を紹介することです。

ワークショップのシナリオは、Kubernetes にシンプルな(計装されていない)Java マイクロサービスアプリケーションをインストールすることで作成されます。

既存の Java ベースのデプロイメント向けに自動ディスカバリー機能付きの Splunk OpenTelemetry Collector をインストールする簡単な手順に従うことで、メトリクス、トレース、ログを Splunk Observability Cloud に送信することがいかに簡単かを確認できます。

前提条件
  • ポート 2222 へのアウトバウンド SSH アクセス
  • ポート 81 へのアウトバウンド HTTP アクセス
  • Linux コマンドラインの基本的な知識

このワークショップでは、以下のコンポーネントをカバーします:

  • Splunk Infrastructure Monitoring (IM)
  • Splunk automatic discovery and configuration for Java (APM)
    • Database Query Performance
    • AlwaysOn Profiling
  • Splunk Log Observer (LO)
  • Splunk Real User Monitoring (RUM)

Splunk Synthetics は少し寂しそうですが、他のワークショップでカバーしています

Last Modified 2025/12/05

PetClinic Kubernetes ワークショップのサブセクション

アーキテクチャ

5 minutes  

Spring PetClinic Java アプリケーションは、フロントエンドとバックエンドのサービスで構成されるシンプルなマイクロサービスアプリケーションです。フロントエンドサービスは、バックエンドサービスと対話するための Web インターフェースを提供する Spring Boot アプリケーションです。バックエンドサービスは、MySQL データベースと対話するための RESTful API を提供する Spring Boot アプリケーションです。

このワークショップを終えるころには、Kubernetes で実行される Java ベースのアプリケーション向けの自動ディスカバリーおよび設定を有効にする方法をより深く理解できるようになります。

以下の図は、Splunk OpenTelemetry Operator と自動ディスカバリーおよび設定を有効にした状態で Kubernetes 上で実行される Spring PetClinic Java アプリケーションのアーキテクチャを詳しく示しています。

Splunk Otel Architecture Splunk Otel Architecture


Josh Voravong が作成したサンプルに基づいています。

Last Modified 2025/12/05

ワークショップインスタンスの準備

15 minutes  

インストラクターが、このワークショップで使用するインスタンスのログイン情報を提供します。

インスタンスに初めてログインすると、以下のような Splunk ロゴが表示されます。ワークショップインスタンスへの接続に問題がある場合は、インストラクターにお問い合わせください。

$ ssh -p 2222 splunk@<IP-ADDRESS>

███████╗██████╗ ██╗     ██╗   ██╗███╗   ██╗██╗  ██╗    ██╗
██╔════╝██╔══██╗██║     ██║   ██║████╗  ██║██║ ██╔╝    ╚██╗
███████╗██████╔╝██║     ██║   ██║██╔██╗ ██║█████╔╝      ╚██╗
╚════██║██╔═══╝ ██║     ██║   ██║██║╚██╗██║██╔═██╗      ██╔╝
███████║██║     ███████╗╚██████╔╝██║ ╚████║██║  ██╗    ██╔╝
╚══════╝╚═╝     ╚══════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝    ╚═╝
Last login: Mon Feb  5 11:04:54 2024 from [Redacted]
splunk@show-no-config-i-0d1b29d967cb2e6ff ~ $

インスタンスが正しく設定されていることを確認するために、このワークショップに必要な環境変数が正しく設定されているか確認する必要があります。ターミナルで以下のスクリプトを実行し、環境変数が存在し、実際の有効な値が設定されていることを確認してください:

. ~/workshop/petclinic/scripts/check_env.sh
ACCESS_TOKEN = <redacted>
REALM = <e.g. eu0, us1, us2, jp0, au0 etc.>
RUM_TOKEN = <redacted>
HEC_TOKEN = <redacted>
HEC_URL = https://<...>/services/collector/event
INSTANCE = <instance_name>

INSTANCE 環境変数の値をメモしておいてください。後で Splunk Observability Cloud でデータをフィルタリングする際に使用します。

このワークショップでは、上記の環境変数がすべて必要です。値が不足しているものがある場合は、インストラクターに連絡してください。

既存の OpenTelemetry Collector の削除

この EC2 インスタンスを使用して以前に Splunk Observability ワークショップを完了している場合は、 既存の Splunk OpenTelemetry Collector のインストールが削除されていることを確認する必要があります。 これは以下のコマンドを実行することで行えます:

helm delete splunk-otel-collector
Last Modified 2025/12/05

2. 準備のサブセクション

Splunk OpenTelemetry Collector のデプロイ

オブザーバビリティシグナル(メトリクス、トレースログ)を Splunk Observability Cloud に送信するには、Kubernetes クラスターに Splunk OpenTelemetry Collector をデプロイする必要があります。

このワークショップでは、Splunk OpenTelemetry Collector Helm Chart を使用します。まず、Helm chart リポジトリを Helm に追加し、helm repo update を実行して最新バージョンを確認します:

helm repo add splunk-otel-collector-chart https://signalfx.github.io/splunk-otel-collector-chart && helm repo update
Using ACCESS_TOKEN={REDACTED}
Using REALM=eu0
"splunk-otel-collector-chart" has been added to your repositories
Using ACCESS_TOKEN={REDACTED}
Using REALM=eu0
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "splunk-otel-collector-chart" chart repository
Update Complete. ⎈Happy Helming!⎈

Splunk Observability Cloud では、Kubernetes 上での OpenTelemetry Collector のセットアップを案内する UI ウィザードが提供されていますが、時間の都合上、以下の Helm install コマンドを使用します。自動ディスカバリーおよび設定とコードプロファイリング用のオペレーターを有効にするための追加パラメータが設定されています。

  • --set="operator.enabled=true" - 自動ディスカバリーおよび設定を処理するための OpenTelemetry オペレーターをインストールします。
  • --set="splunkObservability.profilingEnabled=true" - オペレーター経由でコードプロファイリングを有効にします。

Collector をインストールするには、以下のコマンドを実行してください。これを編集しないでください

helm install splunk-otel-collector --version 0.136.0 \
--set="operatorcrds.install=true", \
--set="operator.enabled=true", \
--set="splunkObservability.realm=$REALM" \
--set="splunkObservability.accessToken=$ACCESS_TOKEN" \
--set="clusterName=$INSTANCE-k3s-cluster" \
--set="splunkObservability.profilingEnabled=true" \
--set="agent.service.enabled=true"  \
--set="environment=$INSTANCE-workshop" \
--set="splunkPlatform.endpoint=$HEC_URL" \
--set="splunkPlatform.token=$HEC_TOKEN" \
--set="splunkPlatform.index=splunk4rookies-workshop" \
splunk-otel-collector-chart/splunk-otel-collector \
-f ~/workshop/k3s/otel-collector.yaml
LAST DEPLOYED: Fri Apr 19 09:39:54 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
Splunk OpenTelemetry Collector is installed and configured to send data to Splunk Platform endpoint "https://http-inputs-o11y-workshop-eu0.splunkcloud.com:443/services/collector/event".

Splunk OpenTelemetry Collector is installed and configured to send data to Splunk Observability realm eu0.

[INFO] You've enabled the operator's auto-instrumentation feature (operator.enabled=true)! The operator can automatically instrument Kubernetes hosted applications.
  - Status: Instrumentation language maturity varies. See `operator.instrumentation.spec` and documentation for utilized instrumentation details.
  - Splunk Support: We offer full support for Splunk distributions and best-effort support for native OpenTelemetry distributions of auto-instrumentation libraries.

続行する前に、Pod が Running として報告されていることを確認してください(通常約30秒かかります)。

kubectl get pods | grep splunk-otel
splunk-otel-collector-k8s-cluster-receiver-6bd5567d95-5f8cj     1/1     Running   0          10m
splunk-otel-collector-agent-tspd2                               1/1     Running   0          10m
splunk-otel-collector-operator-69d476cb7-j7zwd                  2/2     Running   0          10m

Splunk OpenTelemetry Collector からエラーが報告されていないことを確認してください(ctrl + c で終了)。または、インストール済みの素晴らしい k9s ターミナル UI を使用するとボーナスポイントです!

kubectl logs -l app=splunk-otel-collector -f --container otel-collector
2021-03-21T16:11:10.900Z        INFO    service/service.go:364  Starting receivers...
2021-03-21T16:11:10.900Z        INFO    builder/receivers_builder.go:70 Receiver is starting... {"component_kind": "receiver", "component_type": "prometheus", "component_name": "prometheus"}
2021-03-21T16:11:11.009Z        INFO    builder/receivers_builder.go:75 Receiver started.       {"component_kind": "receiver", "component_type": "prometheus", "component_name": "prometheus"}
2021-03-21T16:11:11.009Z        INFO    builder/receivers_builder.go:70 Receiver is starting... {"component_kind": "receiver", "component_type": "k8s_cluster", "component_name": "k8s_cluster"}
2021-03-21T16:11:11.009Z        INFO    k8sclusterreceiver@v0.21.0/watcher.go:195       Configured Kubernetes MetadataExporter  {"component_kind": "receiver", "component_type": "k8s_cluster", "component_name": "k8s_cluster", "exporter_name": "signalfx"}
2021-03-21T16:11:11.009Z        INFO    builder/receivers_builder.go:75 Receiver started.       {"component_kind": "receiver", "component_type": "k8s_cluster", "component_name": "k8s_cluster"}
2021-03-21T16:11:11.009Z        INFO    healthcheck/handler.go:128      Health Check state change       {"component_kind": "extension", "component_type": "health_check", "component_name": "health_check", "status": "ready"}
2021-03-21T16:11:11.009Z        INFO    service/service.go:267  Everything is ready. Begin running and processing data.
2021-03-21T16:11:11.009Z        INFO    k8sclusterreceiver@v0.21.0/receiver.go:59       Starting shared informers and wait for initial cache sync.      {"component_kind": "receiver", "component_type": "k8s_cluster", "component_name": "k8s_cluster"}
2021-03-21T16:11:11.281Z        INFO    k8sclusterreceiver@v0.21.0/receiver.go:75       Completed syncing shared informer caches.       {"component_kind": "receiver", "component_type": "k8s_cluster", "component_name": "k8s_cluster"}
失敗したインストールの削除

OpenTelemetry Collector のインストールでエラーが発生した場合は、 以下のコマンドでインストールを削除してやり直すことができます:

helm delete splunk-otel-collector
Last Modified 2025/12/05

PetClinic アプリケーションのデプロイ

アプリケーションの最初のデプロイメントでは、ビルド済みのコンテナを使用して、観測を開始したい Kubernetes で実行される通常の Java マイクロサービスベースのアプリケーションという基本シナリオを作成します。それでは、アプリケーションをデプロイしましょう:

kubectl apply -f ~/workshop/petclinic/deployment.yaml
deployment.apps/config-server created
service/config-server created
deployment.apps/discovery-server created
service/discovery-server created
deployment.apps/api-gateway created
service/api-gateway created
service/api-gateway-external created
deployment.apps/customers-service created
service/customers-service created
deployment.apps/vets-service created
service/vets-service created
deployment.apps/visits-service created
service/visits-service created
deployment.apps/admin-server created
service/admin-server created
service/petclinic-db created
deployment.apps/petclinic-db created
configmap/petclinic-db-initdb-config created
deployment.apps/petclinic-loadgen-deployment created
configmap/scriptfile created

この時点で、Pod が実行されていることを確認してデプロイメントを検証できます。コンテナのダウンロードと起動が必要なため、数分かかる場合があります。

kubectl get pods
NAME                                                            READY   STATUS    RESTARTS   AGE
splunk-otel-collector-k8s-cluster-receiver-655dcd9b6b-dcvkb     1/1     Running   0          114s
splunk-otel-collector-agent-dg2vj                               1/1     Running   0          114s
splunk-otel-collector-operator-57cbb8d7b4-dk5wf                 2/2     Running   0          114s
petclinic-db-64d998bb66-2vzpn                                   1/1     Running   0          58s
api-gateway-d88bc765-jd5lg                                      1/1     Running   0          58s
visits-service-7f97b6c579-bh9zj                                 1/1     Running   0          58s
admin-server-76d8b956c5-mb2zv                                   1/1     Running   0          58s
customers-service-847db99f79-mzlg2                              1/1     Running   0          58s
vets-service-7bdcd7dd6d-2tcfd                                   1/1     Running   0          58s
petclinic-loadgen-deployment-5d69d7f4dd-xxkn4                   1/1     Running   0          58s
config-server-67f7876d48-qrsr5                                  1/1     Running   0          58s
discovery-server-554b45cfb-bqhgt                                1/1     Running   0          58s

kubectl get pods の出力が、上記の Output タブに示されている出力と一致することを確認してください。すべてのサービスが Running と表示されていることを確認してください(または k9s を使用してステータスを継続的に監視できます)。

アプリケーションをテストするには、インスタンスのパブリック IP アドレスを取得する必要があります。以下のコマンドを実行して取得できます:

curl http://ifconfig.me

http://<IP_ADDRESS>:81<IP_ADDRESS> を上記で取得した IP アドレスに置き換えてください)にアクセスして、アプリケーションが実行されていることを確認してください。PetClinic アプリケーションが実行されているのが確認できるはずです。アプリケーションはポート 80443 でも実行されているので、これらを使用するか、ポート 81 に到達できない場合はそちらを使用してください。

Pet shop Pet shop

All Owners (1) タブと Veterinarians (2) タブにアクセスして、各ページに名前のリストが表示されることを確認し、アプリケーションが正しく動作していることを確認してください。

Owners Owners

Last Modified 2025/12/05

Kubernetes クラスターメトリクスの確認

10 minutes  

インストールが完了したら、Splunk Observability Cloud にログインして、Kubernetes クラスターからメトリクスが流れてきていることを確認できます。

左側のメニューから Infrastructure をクリックし、Kubernetes を選択してから、Kubernetes nodes タイルを選択します。

NavigatorList NavigatorList

Kubernetes nodes の概要画面に入ったら、Time フィルタを -1h から過去15分 (-15m) に変更して最新のデータに焦点を当て、次に Table を選択してメトリクスを報告しているすべてのノードをリスト表示します。

次に、Refine by: パネルで Cluster name を選択し、リストからご自身のクラスターを選択します。

Tip

特定のクラスターを識別するには、セットアップ中に実行したシェルスクリプト出力の INSTANCE 値を使用してください。この一意の識別子により、リスト内の他のノードの中からワークショップクラスターを見つけることができます。

これにより、ご自身のクラスターのノードのみを表示するようにリストがフィルタリングされます。

K8s Nodes K8s Nodes

K8s node logs ビューに切り替えて、ノードからのログを確認します。

Logs Logs

Last Modified 2025/12/05

APMの自動検出と設定のセットアップ

10分  

このセクションでは、Kubernetes 上で実行されている Java サービスに対して自動検出と設定を有効化します。これにより、OpenTelemetry Collector が Pod アノテーションを検索し、Java アプリケーションに Splunk OpenTelemetry Java エージェントで計装を行う必要があることを示します。これにより、クラスター上で実行されている Java サービスからトレース、スパン、およびプロファイリングデータを取得できるようになります。

自動検出と設定

自動検出と設定は、コード変更や再コンパイルを必要とせずにアプリケーションからトレース、スパン、およびプロファイリングデータを取得するように設計されていることを理解することが重要です。

これは APM を始めるための優れた方法ですが、手動計装 の代替ではありません。手動計装では、カスタムスパン、タグ、ログをアプリケーションに追加でき、トレースにより多くのコンテキストと詳細を提供できます。

Java アプリケーションの場合、OpenTelemetry Collector はinstrumentation.opentelemetry.io/inject-javaというアノテーションを検索します。

このアノテーションの値はtrueに設定するか、OpenTelemetry Collector のnamespace/daemonset(例:default/splunk-otel-collector)に設定できます。これにより、名前空間をまたいで動作することができ、このワークショップではこれを使用します。

deployment.yamlの使用

Pod が自動的にトレースを送信するようにしたい場合は、以下に示すようにdeployment.yamlにアノテーションを追加できます。これにより、初期デプロイメント時に計装ライブラリが追加されます。時間を節約するために、以下の Pod に対してこれを実施済みです:

  • admin-server
  • config-server
  • discovery-server
apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-server
  labels:
    app.kubernetes.io/part-of: spring-petclinic
spec:
  selector:
    matchLabels:
      app: admin-server
  template:
    metadata:
      labels:
        app: admin-server
      annotations:
        instrumentation.opentelemetry.io/inject-java: "default/splunk-otel-collector"
Last Modified 2026/01/05

4. 自動検出と設定のサブセクション

デプロイメントのパッチ適用

自動検出と設定を構成するには、デプロイメントに計装アノテーションを追加するためのパッチを適用する必要があります。パッチが適用されると、OpenTelemetry Collectorが自動検出と設定ライブラリを注入し、Podが再起動されてトレースとプロファイリングデータの送信が開始されます。まず、以下を実行してapi-gatewaysplunk-otel-javaイメージがないことを確認します:

kubectl describe pods api-gateway | grep Image:
Image:         quay.io/phagen/spring-petclinic-api-gateway:0.0.2

次に、デプロイメントにアノテーションを追加して、すべてのサービスのJava自動検出と設定を有効にします。以下のコマンドは、すべてのデプロイメントにパッチを適用します。これにより、OpenTelemetry Operatorがsplunk-otel-javaイメージをPodに注入します:

kubectl get deployments -l app.kubernetes.io/part-of=spring-petclinic -o name | xargs -I % kubectl patch % -p "{\"spec\": {\"template\":{\"metadata\":{\"annotations\":{\"instrumentation.opentelemetry.io/inject-java\":\"default/splunk-otel-collector\"}}}}}"
deployment.apps/config-server patched (no change)
deployment.apps/admin-server patched (no change)
deployment.apps/customers-service patched
deployment.apps/visits-service patched
deployment.apps/discovery-server patched (no change)
deployment.apps/vets-service patched
deployment.apps/api-gateway patched

config-serverdiscovery-serveradmin-serverについては、すでにパッチが適用されているため変更はありません。

api-gateway Podのコンテナイメージを再度確認するには、以下のコマンドを実行します:

kubectl describe pods api-gateway | grep Image:
Image:         ghcr.io/signalfx/splunk-otel-java/splunk-otel-java:v1.30.0
Image:         quay.io/phagen/spring-petclinic-api-gateway:0.0.2

api-gatewayに新しいイメージが追加され、ghcr.ioからsplunk-otel-javaがプルされます(注:2つのapi-gatewayコンテナが表示される場合、元のコンテナがまだ終了処理中の可能性があるため、数秒待ってください)。

Splunk Observability CloudのKubernetes Navigatorに戻ります。数分後、Podがオペレーターによって再起動され、自動検出と設定コンテナが追加されることが確認できます。以下のスクリーンショットのような表示になります:

restart restart

Kubernetes NavigatorでPodが緑色になるまで待ってから、次のセクションに進んでください。

Last Modified 2026/01/05

Splunk APMでのデータの表示

左側のメニューでAPMをクリックして、新しく計装されたサービスからのトレースによって生成されたデータを確認します。

ドロップダウンボックスでEnvironmentフィルター (1) をワークショップインスタンスの名前に変更します。

メモ

これは**<INSTANCE>-workshopになります。ここでINSTANCE**は、先ほど実行したシェルスクリプトの値です。これのみが選択されていることを確認してください。

apm apm

Service Map (2) ペインをクリックして、次のセクションの準備をします。

Last Modified 2026/01/05

APM Features

15 minutes  

前のセクションで見てきたように、サービスで自動検出と設定を有効にすると、トレースがSplunk Observability Cloudに送信されます。

これらのトレースにより、Splunkは自動的にService MapsRED Metricsを生成します。これらは、サービスの動作とサービス間の相互作用を理解するための最初のステップです。

次のセクションでは、トレース自体と、コードに触れることなくサービスの動作を理解するのに役立つ情報を詳しく見ていきます。

Last Modified 2026/01/05

5. APM Featuresのサブセクション

APM Service Map

apm map apm map

上記のマップは、すべてのサービス間のすべての相互作用を示しています。PetClinic Microserviceアプリケーションが起動して完全に同期するまで数分かかるため、マップはまだ中間状態にある可能性があります。時間フィルタを**-2mと入力してカスタム時間の2分に減らすと役立ちます。画面右上のRefreshボタン(1)**をクリックできます。赤い円で示される初期起動関連のエラーは最終的に消えます。

次に、各サービスで利用可能なメトリクスを調べるために、リクエスト、エラー、期間(RED)メトリクスダッシュボードを見てみましょう。

この演習では、サービスオペレーションが高いレイテンシやエラーを示している場合に使用する一般的なシナリオを使用します。

依存関係マップでcustomers-serviceをクリックし、Servicesドロップダウンボックス**(1)customers-serviceが選択されていることを確認します。次に、サービス名に隣接するOperationsドロップダウン(2)**からGET /ownersを選択します。

これにより、以下に示すようにGET /ownersでフィルタリングされたワークフローが表示されます:

select a trace select a trace

Last Modified 2026/01/05

APM Trace

トレースを選択するには、Service Requests & Errorsチャート**(1)**の線を選択します。関連するトレースの選択肢が表示されます。

関連するトレースのリストが表示されたら、青い**(2)** Trace ID Linkをクリックします。選択するトレースがServicesカラムに記載されている3つのサービスと同じものであることを確認してください。

workflow-trace-pick workflow-trace-pick

これにより、ウォーターフォールビューで選択されたトレースが表示されます:

ここにはいくつかのセクションがあります:

  • Waterfall Pane (1):トレースとスパンとして表示されるすべてのインストルメントされた関数が、その期間表示と順序/関係とともに表示されます。
  • Trace Info Pane (2):選択されたスパン情報が表示されます(Waterfall Pane内でスパンの周りにボックスでハイライトされています)。
  • Span Pane (3):選択されたスパンで送信されたすべてのタグを見つけることができます。下にスクロールしてすべてを確認できます。
  • Process Pane:スパンを作成したプロセスに関連するタグが表示されます(スクリーンショットに含まれていないため、下にスクロールして確認してください)。
  • Trace Properties:ペインの右上にあり、デフォルトでは折りたたまれています。

waterfall waterfall

Last Modified 2026/01/05

APM Span

スパンを調べる際、トレーシングの上で自動検出と設定を使用すると、コード変更なしで得られるいくつかの標準機能を見てみましょう:

まず、Waterfall Paneで、以下のスクリーンショットに示すようにcustomers-service:SELECT petclinicまたは類似のスパンが選択されていることを確認してください:

DB-query DB-query

  • 基本的なレイテンシ情報は、インストルメントされた関数または呼び出しのバーとして表示されます。上記の例では、17.8ミリ秒かかりました。
  • いくつかの類似したスパン**(1)**は、スパンが複数回繰り返される場合にのみ表示されます。この場合、例では10回の繰り返しがあります。10xをクリックすると、すべてのスパンが順番に表示されるように表示/非表示を切り替えることができます。
  • Inferred Services:インストルメントされていない外部システムへの呼び出しは、グレーの「推測された」スパンとして表示されます。この例のInferred Serviceまたはスパンは、上記に示すようにMysqlデータベース mysql:petclinic SELECT petclinic **(2)**への呼び出しです。
  • Span Tags:Tag Paneには、自動検出と設定によって生成された標準タグが表示されます。この場合、スパンはデータベースを呼び出しているため、db.statementタグ**(3)**が含まれています。このタグは、このスパン中に実行されたデータベース呼び出しで使用されるDBクエリステートメントを保持します。これはDB-Query Performance機能で使用されます。DB-Query Performanceについては次のセクションで見ていきます。
  • Always-on Profiling:システムがスパンのライフサイクル中にプロファイリングデータをキャプチャするように設定されている場合、スパンのタイムラインでキャプチャされたコールスタックの数が表示されます。上記の例では、customer-service:GET /ownersスパンに対して18個のコールスタックがあることがわかります。(4)

次のセクションでプロファイリングを見ていきます。

Last Modified 2026/01/05

Service Centric View

Splunk APMは、エンジニアに1つの集中ビューでサービスパフォーマンスの深い理解を提供するService Centric Viewsを提供します。すべてのサービスにわたって、エンジニアはサービスの基盤となるインフラストラクチャからのエラーやボトルネックを迅速に特定し、新しいデプロイによるパフォーマンス低下を特定し、すべてのサードパーティ依存関係の健全性を可視化できます。

api-gatewayのこのダッシュボードを表示するには、左側のメニューからAPMをクリックし、リストのapi-gatewayサービスをクリックします。これにより、Service Centric Viewダッシュボードが表示されます:

service_maps service_maps

インストルメントされた各サービスで利用可能なこのビューは、Service metricsError breakdownRuntime metrics (Java)Infrastructure metricsの概要を提供します。

Last Modified 2026/01/05

Always-On Profiling & DB Query Performance

15 minutes  

前の章で見てきたように、APMを使用して、コードに触れることなく、さまざまなサービス間のインタラクションをトレースすることができ、問題をより迅速に特定できます。

トレーシングに加えて、automatic discovery and configurationは、問題をさらに迅速に発見するのに役立つ追加機能を最初から提供します。このセクションでは、そのうちの2つを見ていきます:

  • Always-on Profiling and Java Metrics
  • Database Query Performance

Always-on ProfilingまたはDatabase Query Performanceについてさらに深く学びたい場合は、Debug Problems in Microservicesという別のNinja Workshopがありますので、そちらをご覧ください。

Last Modified 2026/01/05

6. Advanced Featuresのサブセクション

Always-On Profiling & Metrics

先ほどHelmチャートを使用してSplunk Distribution of the OpenTelemetry Collectorをインストールした際、AlwaysOn ProfilingMetricsを有効にするように設定しました。これにより、OpenTelemetry JavaはアプリケーションのCPUとメモリのプロファイリングを自動的に生成し、Splunk Observability Cloudに送信します。

PetClinicアプリケーションをデプロイしてアノテーションを設定すると、collectorは自動的にアプリケーションを検出し、トレースとプロファイリングのためにインストルメントします。これを確認するために、次のスクリプトを実行して、インストルメントしているJavaコンテナの1つの起動ログを調べることができます:

ログには、Javaの自動検出と設定によって取得されたフラグが表示されます:

.  ~/workshop/petclinic/scripts/get_logs.sh
2024/02/15 09:42:00 Problem with dial: dial tcp 10.43.104.25:8761: connect: connection refused. Sleeping 1s
2024/02/15 09:42:01 Problem with dial: dial tcp 10.43.104.25:8761: connect: connection refused. Sleeping 1s
2024/02/15 09:42:02 Connected to tcp://discovery-server:8761
Picked up JAVA_TOOL_OPTIONS:  -javaagent:/otel-auto-instrumentation-java/javaagent.jar
Picked up _JAVA_OPTIONS: -Dspring.profiles.active=docker,mysql -Dsplunk.profiler.call.stack.interval=150
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
[otel.javaagent 2024-02-15 09:42:03:056 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: splunk-1.30.1-otel-1.32.1
[otel.javaagent 2024-02-15 09:42:03:768 +0000] [main] INFO com.splunk.javaagent.shaded.io.micrometer.core.instrument.push.PushMeterRegistry - publishing metrics for SignalFxMeterRegistry every 30s
[otel.javaagent 2024-02-15 09:42:07:478 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-02-15 09:42:07:478 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - Profiler configuration:
[otel.javaagent 2024-02-15 09:42:07:480 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                  splunk.profiler.enabled : true
[otel.javaagent 2024-02-15 09:42:07:505 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -                splunk.profiler.directory : /tmp
[otel.javaagent 2024-02-15 09:42:07:505 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -       splunk.profiler.recording.duration : 20s
[otel.javaagent 2024-02-15 09:42:07:506 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -               splunk.profiler.keep-files : false
[otel.javaagent 2024-02-15 09:42:07:510 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -            splunk.profiler.logs-endpoint : http://10.13.2.38:4317
[otel.javaagent 2024-02-15 09:42:07:513 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -              otel.exporter.otlp.endpoint : http://10.13.2.38:4317
[otel.javaagent 2024-02-15 09:42:07:513 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -           splunk.profiler.memory.enabled : true
[otel.javaagent 2024-02-15 09:42:07:515 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -             splunk.profiler.tlab.enabled : true
[otel.javaagent 2024-02-15 09:42:07:516 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -        splunk.profiler.memory.event.rate : 150/s
[otel.javaagent 2024-02-15 09:42:07:516 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.call.stack.interval : PT0.15S
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -  splunk.profiler.include.internal.stacks : false
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger -      splunk.profiler.tracing.stacks.only : false
[otel.javaagent 2024-02-15 09:42:07:517 +0000] [main] INFO com.splunk.opentelemetry.profiler.ConfigurationLogger - -----------------------
[otel.javaagent 2024-02-15 09:42:07:518 +0000] [main] INFO com.splunk.opentelemetry.profiler.JfrActivator - Profiler is active.
私たちが注目しているのは、com.splunk.opentelemetry.profiler.ConfigurationLoggerによって書き込まれたセクション、つまりProfiling Configurationです。

splunk.profiler.directoryなど、制御できるさまざまな設定を確認できます。これは、エージェントがSplunkに送信する前にコールスタックを書き込む場所です。(これは、コンテナの設定方法によって異なる場合があります。)

変更したいもう1つのパラメータはsplunk.profiler.call.stack.intervalです。これは、システムがCPU Stack traceをキャプチャする頻度です。Pet Clinicアプリケーションのような短いスパンがある場合は、このインターバル設定を短くすることをお勧めします。デモアプリケーションでは、デフォルトのインターバル値を変更しなかったため、スパンに常にCPU Call Stackが関連付けられているとは限りません。

これらのパラメータを設定する方法はこちらで確認できます。以下の例では、deployment.yamlでコールスタックのより高い収集レートを設定する方法を示しています。これは、JAVA_OPTIONS configセクションでこの値を設定することで行います。

env:
- name: JAVA_OPTIONS
  value: "-Xdebug -Dsplunk.profiler.call.stack.interval=150"
Last Modified 2026/01/05

Trace Waterfall内のAlways-On Profiling

APM Waterfall ビューでオリジナルの Trace & Span (1)(または類似のもの)を選択し、右側のペインから**Memory Stack Traces (2)**を選択してください:

profiling from span profiling from span

ペインに Memory Stack Trace Flame Graph **(3)**が表示されます。スクロールするか、ペインの右側をドラッグして拡大できます。

AlwaysOn Profiling は、アプリケーションのコードのスナップショット、つまりスタックトレースを常に取得しています。何千ものスタックトレースを読まなければならないことを想像してみてください!それは現実的ではありません。これを支援するために、AlwaysOn Profiling はプロファイリングデータを集約して要約し、Flame Graphと呼ばれるビューで Call Stacks を探索する便利な方法を提供します。これは、アプリケーションからキャプチャされたすべてのスタックトレースの要約を表します。Flame Graph を使用して、パフォーマンスの問題を引き起こしている可能性のあるコードの行を発見し、コードに加えた変更が意図した効果を持っているかどうかを確認できます。

Always-on Profiling をさらに詳しく調べるには、Memory Stack Tracesの下の Profiling Pane で上の画像で参照されている Span **(3)**を選択してください。これにより、Always-on Profiling のメイン画面が開き、Memory ビューがあらかじめ選択されています:

Profiling main Profiling main

  • Time フィルタは、選択したスパンの時間枠に設定されます (1)
  • Java Memory Metric Charts **(2)**では、Heap MemoryのモニターMemory Allocation RateGarbage Collecting Metrics などのApplication Activityを確認できます。
  • スパン **(3)**に関連するメトリクスと Stack Traces のみにフォーカス/表示する機能。これにより、必要に応じて Java アプリケーションで実行されているバックグラウンドアクティビティをフィルタで除外できます。
  • 識別された Java Function calls **(4)**により、その関数から呼び出されたメソッドにドリルダウンできます。
  • プロファイルされたサービスのスタックトレースに基づく階層の視覚化を持つ Flame Graph (5)
  • サービスが複数のバージョンを起動する場合に備えて、Service instance **(6)**を選択する機能。

さらなる調査のために、UI ではスタックトレースをクリックして、呼び出された関数と、フレームチャートから関連する行を確認できます。これを使用して、コーディングプラットフォームで実際のコードの行を表示できます(もちろん、お好みのコーディングプラットフォームによって異なります)。

Last Modified 2026/01/05

Database Query Performance

Database Query Performanceを使用すると、Splunk APMで直接、データベースクエリがサービスの可用性に与える影響をモニターできます。これにより、データベースをインストルメントすることなく、長時間実行されるクエリ、最適化されていないクエリ、または重いクエリを迅速に特定し、それらが引き起こしている可能性のある問題を軽減できます。

データベースクエリのパフォーマンスを確認するには、ブラウザで戻るか、メニューバーのAPMセクションに移動してAPMのService Mapページに移動し、Service Mapタイルをクリックします。

Dependency mapで推論されたデータベースサービス mysql:petclinic Inferred Database serverを選択し (1)、次に右側のペインをスクロールしてDatabase Query Performance Pane **(2)**を見つけます。

DB-query from map DB-query from map

マップで選択したサービスが実際に(推論された)データベースサーバーである場合、このペインには期間に基づく上位90%(P90)のデータベースコールが表示されます。db-queryパフォーマンス機能をさらに詳しく調べるには、ペインの上部にあるDatabase Query Performanceという単語のどこかをクリックします。

これにより、DB-query Performanceの概要画面が表示されます:

DB-query full DB-query full

Database Query Normalization

デフォルトでは、Splunk APMインストルメンテーションはデータベースクエリをサニタイズして、db.statementsからシークレットや個人を特定できる情報(PII)などの機密データを削除またはマスクします。データベースクエリの正規化をオフにする方法はこちらで確認できます。

この画面には、Splunk Observability Cloudに送信されたTraces & Spansに基づいて、アプリケーションからデータベースに対して実行されたすべてのDatabase queries **(1)**が表示されます。時間ブロック間で比較したり、Total Time、P90 Latency & Requests **(2)**でソートしたりできることに注意してください。

リスト内の各Database queryについて、時間ウィンドウ中の最高レイテンシ、コールの総数、および1秒あたりのリクエスト数 **(3)**が表示されます。これにより、クエリを最適化できる場所を特定できます。

右側のペイン **(5)**の2つのチャートを使用して、Database Callsを含むトレースを選択できます。Tag Spotlightペイン **(6)**を使用して、エンドポイントやタグに基づいて、データベースコールに関連するタグを確認します。

クエリの詳細ビューを表示する必要がある場合:

details details

特定のQuery **(1)**をクリックします。これにより、Query Details pane **(2)**が開き、より詳細な調査に使用できます。

Last Modified 2026/01/05

Log Observer

10 minutes  

この時点まで、コード変更は一切なく、トレーシング、プロファイリング、データベースクエリパフォーマンスのデータが Splunk Observability Cloud に送信されています。

次に、Splunk Log Observer を使用して Spring PetClinic アプリケーションからログデータを取得します。

Splunk OpenTelemetry Collector は、Spring PetClinic アプリケーションからログを自動的に収集し、OTLP エクスポーターを使用して Splunk Observability Cloud に送信します。その際、ログイベントには trace_idspan_id、トレースフラグが付与されます。

Splunk Log Observer を使用してログを表示し、ログ情報をサービスやトレースと自動的に関連付けます。

この機能は Related Content と呼ばれています。

Last Modified 2026/01/05

7. Log Observerのサブセクション

ログを確認する

ログを表示するには、左側のメニューで Logo Logo Log Observer をクリックします。Log Observer に入ったら、フィルターバーの Indexsplunk4rookies-workshop に設定されていることを確認してください。(1)

次に、Add Filter をクリックし、Fields (2) オプションを使用して deployment.environment フィールド (3) を検索します。ドロップダウンリストから、あなたのワークショップインスタンスを選択し (4)= (含める) をクリックします。これで、PetClinic アプリケーションからのログメッセージのみが表示されます。

Log Observer sort Log Observer sort

次に、service.name フィールドを検索し、値 customers-service を選択して = (含める) をクリックします。これがフィルターバー (1) に表示されます。次に、Run Search ボタン (2) をクリックします。

Log Observer run Log Observer run

これによりログエントリがリフレッシュされ、customers-service からのエントリのみが表示されるように絞り込まれます。

Log Observer Log Observer

“Saving pet” で始まるエントリ (1) をクリックします。サイドペーンが開き、関連するトレースIDやスパンID (2) を含む詳細情報を確認できます。

Last Modified 2026/01/05

Related Content

下部のペインには、関連するコンテンツが表示されます。以下のスクリーンショットでは、APM がこのログ行に関連するトレースを見つけたことがわかります (1):

RC RC

Trace for 960432ac9f16b98be84618778905af50 (2) をクリックすると、このログ行が生成された特定のトレースの APM ウォーターフォールに移動します:

waterfall logs waterfall logs

ログに関する Related Content ペーンが表示されていることに注意してください (1)。これをクリックすると、Log Observer に戻り、このトレースの一部であるすべてのログ行が表示されます。

Last Modified 2026/01/05

Real User Monitoring

10 minutes  

アプリケーションに Real User Monitoring (RUM) インストルメンテーションを有効にするには、コードベースに Open Telemetry Javascript https://github.com/signalfx/splunk-otel-js-web スニペットを追加する必要があります。

Spring PetClinic アプリケーションは、アプリケーションのすべてのビューで再利用される単一の index HTML ページを使用しています。これは、Splunk RUM インストルメンテーションライブラリを挿入するのに最適な場所です。すべてのページで自動的に読み込まれるためです。

api-gateway サービスはすでにインストルメンテーションを実行しており、RUM トレースを Splunk Observability Cloud に送信しています。次のセクションでデータを確認します。

スニペットを確認したい場合は、ブラウザでページを右クリックして View Page Source を選択することで、ページソースを表示できます。

    <script src="/env.js"></script>
    <script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
    <script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web-session-recorder.js" crossorigin="anonymous"></script>
    <script>
        var realm = env.RUM_REALM;
        console.log('Realm:', realm);
        var auth = env.RUM_AUTH;
        var appName = env.RUM_APP_NAME;
        var environmentName = env.RUM_ENVIRONMENT
        if (realm && auth) {
            SplunkRum.init({
                realm: realm,
                rumAccessToken: auth,
                applicationName: appName,
                deploymentEnvironment: environmentName,
                version: '1.0.0',
            });

            SplunkSessionRecorder.init({
                applicationName: appName,
                realm: realm,
                rumAccessToken: auth,
                  recorder: "splunk",
                  features: {
                    video: true,
                }
            });
            const Provider = SplunkRum.provider;
            var tracer=Provider.getTracer('appModuleLoader');
        } else {
        // Realm or auth is empty, provide default values or skip initialization
        console.log("Realm or auth is empty. Skipping Splunk Rum initialization.");
        }
    </script>
     <!-- Section added for  RUM -->
Last Modified 2026/01/05

8. Real User Monitoringのサブセクション

Select the RUM view for the Petclinic App

左側のメニューで RUM をクリックして、RUM の簡単な概要ツアーを始めましょう。次に、Environment フィルター (1) をドロップダウンボックスから変更し、ワークショップインスタンスの名前 <INSTANCE>-workshop (1) を選択します (ここで INSTANCE は、以前に実行したシェルスクリプトの値です)。これのみが選択されていることを確認してください。

次に、App (2) ドロップダウンボックスをアプリの名前に変更します。これは <INSTANCE>-store になります。

rum select rum select

EnvironmentApp を選択すると、アプリケーションの RUM ステータスを示す概要ページが表示されます。(Summary Dashboard が単一行の数値だけの場合は、縮小表示になっています。アプリケーション名の前にある > (1) をクリックして展開できます)。JavaScript エラーが発生した場合は、以下のように表示されます:

rum overview rum overview

続けるには、青いリンク (ワークショップ名) をクリックして詳細ページに移動します。これにより、UX Metrics、Front-end Health、Back-end Health、Custom Events によるインタラクションの内訳が表示され、過去のメトリクス (デフォルトでは 1 時間) と比較される新しいダッシュボードビューが表示されます。

rum  main rum  main 通常、最初のチャートには 1 つの線のみがあります。Petclinic ショップに関連するリンクをクリックしてください。 この例では http://198.19.249.202:81 です:

これにより、Tag Spotlight ページに移動します。

Last Modified 2026/01/05

RUM trace Waterfall view & linking to APM

TAG Spotlight ビューでは、RUM データに関連付けられたすべてのタグが表示されます。タグは、データを識別するために使用されるキーバリューペアです。この場合、タグは OpenTelemetry インストルメンテーションによって自動的に生成されます。タグは、データをフィルタリングし、チャートやテーブルを作成するために使用されます。Tag Spotlight ビューでは、動作の傾向を検出し、ユーザーセッションにドリルダウンできます。

RUM TAG RUM TAG

User Sessions (1) をクリックすると、タイムウィンドウ中に発生したユーザーセッションのリストが表示されます。

セッションの 1 つを見たいので、Duration (2) をクリックして期間でソートし、長いものの 1 つのリンク (3) をクリックしてください:

User sessions User sessions

Last Modified 2026/01/05

RUM trace Waterfall view & linking to APM

RUM トレースウォーターフォールを見ています。これは、ユーザーが petclinic アプリケーションのページにアクセスしたときに、ユーザーデバイス上で何が起こったかを示します。

ウォーターフォールを下にスクロールして、右側の #!/owners/details セグメント (1) を見つけてクリックすると、Vets リクエストの処理中に発生したアクションのリストが表示されます。HTTP リクエストには、リターンコードの前に青い APM リンクがあることに注意してください。1 つを選択し、APM リンクをクリックします。これにより、Kubernetes でホストされているこのバックエンドサービスコールの APM 情報が表示されます。

rum apm link rum apm link

リクエストで何が起こったかを確認するためにドリルダウンしたい場合は、Trace ID の URL をクリックしてください。

これにより、RUM からのリクエストに関連するトレースが表示されます:

RUm-apm linked RUm-apm linked

サービスへのエントリーポイントに RUM (1) 関連コンテンツリンクが追加されており、バックエンドサービスで何が起こったかを確認した後、RUM セッションに戻ることができるようになっていることがわかります。

Last Modified 2026/01/05

Workshop Wrap-up 🎁

おめでとうございます。Get the Most Out of Your Existing Kubernetes Java Applications Using Automatic Discovery and Configuration With OpenTelemetry ワークショップを完了しました。

今日、既存の Kubernetes 上の Java アプリケーションにトレース、コードプロファイリング、データベースクエリパフォーマンスを追加することがいかに簡単かを学びました。

Automatic Discovery and Configuration を使用して、コードや設定に一切触れることなく、アプリケーションとインフラストラクチャの可観測性を即座に向上させました。

また、シンプルな設定変更により、さらに多くの可観測性 (loggingRUM) をアプリケーションに追加して、エンドツーエンドの可観測性を提供できることも学びました。

Champagne Champagne

Last Modified 2026/01/05

OpenTelemetry Collector ワークショップ

Last Modified 2026/01/09

OpenTelemetry Collector ワークショップのサブセクション

OpenTelemetry でオブザーバビリティをクラウドネイティブに

1 hour   Author Robert Castley

概要

OpenTelemetry を始めたばかりの組織では、まずオブザーバビリティバックエンドに直接データを送信することから始めることが多いでしょう。これは初期テストには有効ですが、OpenTelemetry Collector をオブザーバビリティアーキテクチャの一部として使用することで多くのメリットがあり、本番環境へのデプロイには推奨されています。

このワークショップでは、OpenTelemetry Collector の使用に焦点を当て、Splunk Observability Cloud で使用するための Receiver、Processor、Exporter の設定の基本から始めます。参加者は初心者から、分散プラットフォームのビジネスオブザーバビリティニーズを解決するためのカスタムコンポーネントを追加できるレベルまで到達します。

Ninja セクション

ワークショップを通じて、展開可能な Ninja セクション があります。これらはより実践的で、ワークショップ中または自分の時間に探求できる詳細な技術情報を提供します。

OpenTelemetry プロジェクトは頻繁に開発が行われているため、これらのセクションの内容が古くなる可能性があることに注意してください。詳細が同期していない場合はリンクが提供されます。更新が必要な箇所を見つけた場合はお知らせください。


Ninja: テストしてみよう!

このワークショップを完了すると、正式に OpenTelemetry Collector Ninja になれます!


対象者

このインタラクティブなワークショップは、OpenTelemetry Collector のアーキテクチャとデプロイについて詳しく学びたい開発者およびシステム管理者を対象としています。

前提条件

  • データ収集の基本的な理解があること
  • コマンドラインと vim/vi の経験があること
  • Ubuntu 20.04 LTS または 22.04 LTS を実行しているインスタンス/ホスト/VM があること
    • 最小要件は AWS/EC2 t2.micro(1 CPU、1GB RAM、8GB ストレージ)です

学習目標

このワークショップを終えると、参加者は以下ができるようになります

  • OpenTelemetry のコンポーネントを理解する
  • Receiver、Processor、Exporter を使用してデータを収集・分析する
  • OpenTelemetry を使用するメリットを理解する
  • ビジネスニーズを解決するカスタムコンポーネントを構築する

OpenTelemetry アーキテクチャ

%%{
  init:{
    "theme":"base",
    "themeVariables": {
      "primaryColor": "#ffffff",
      "clusterBkg": "#eff2fb",
      "defaultLinkColor": "#333333"
    }
  }
}%%

flowchart LR;
    subgraph Collector
    A[OTLP] --> M(Receivers)
    B[JAEGER] --> M(Receivers)
    C[Prometheus] --> M(Receivers)
    end
    subgraph Processors
    M(Receivers) --> H(Filters, Attributes, etc)
    E(Extensions)
    end
    subgraph Exporters
    H(Filters, Attributes, etc) --> S(OTLP)
    H(Filters, Attributes, etc) --> T(JAEGER)
    H(Filters, Attributes, etc) --> U(Prometheus)
    end
Last Modified 2026/01/23

OpenTelemetry Collector の基本概念のサブセクション

OpenTelemetry Collector Contrib のインストール

OpenTelemetry Collector Contrib ディストリビューションのダウンロード

OpenTelemetry Collector をインストールする最初のステップは、ダウンロードです。このラボでは、wget コマンドを使用して OpenTelemetry の GitHub リポジトリから .deb パッケージをダウンロードします。

お使いのプラットフォーム用の .deb パッケージを OpenTelemetry Collector Contrib リリースページ から取得します。

wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.111.0/otelcol-contrib_0.111.0_linux_amd64.deb

OpenTelemetry Collector Contrib ディストリビューションのインストール

dpkg を使用して .deb パッケージをインストールします。インストールが成功した場合の出力例は、下の dpkg Output タブを確認してください

sudo dpkg -i otelcol-contrib_0.111.0_linux_amd64.deb
Selecting previously unselected package otelcol-contrib.
(Reading database ... 89232 files and directories currently installed.)
Preparing to unpack otelcol-contrib_0.111.0_linux_amd64.deb ...
Unpacking otelcol-contrib (0.111.0) ...
Setting up otelcol-contrib (0.111.0) ...
Created symlink /etc/systemd/system/multi-user.target.wants/otelcol-contrib.service → /lib/systemd/system/otelcol-contrib.service.
Last Modified 2026/01/23

1. インストールのサブセクション

OpenTelemetry Collector Contrib のインストール

Collector が動作していることを確認する

Collector が動作しているはずです。systemctl コマンドを使用して root として確認します。ステータス表示を終了するには q を押してください。

sudo systemctl status otelcol-contrib
● otelcol-contrib.service - OpenTelemetry Collector Contrib
     Loaded: loaded (/lib/systemd/system/otelcol-contrib.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-10-07 10:27:49 BST; 52s ago
   Main PID: 17113 (otelcol-contrib)
      Tasks: 13 (limit: 19238)
     Memory: 34.8M
        CPU: 155ms
     CGroup: /system.slice/otelcol-contrib.service
             └─17113 /usr/bin/otelcol-contrib --config=/etc/otelcol-contrib/config.yaml

Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]: Descriptor:
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]:      -> Name: up
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]:      -> Description: The scraping was successful
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]:      -> Unit:
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]:      -> DataType: Gauge
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]: NumberDataPoints #0
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]: StartTimestamp: 1970-01-01 00:00:00 +0000 UTC
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]: Timestamp: 2024-10-07 09:28:36.942 +0000 UTC
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]: Value: 1.000000
Oct 07 10:28:36 petclinic-rum-testing otelcol-contrib[17113]:         {"kind": "exporter", "data_type": "metrics", "name": "debug"}

このワークショップでは、設定ファイルの変更、環境変数の設定、Collector の再起動を複数回行うため、Collector サービスを停止し、起動時の自動起動を無効にする必要があります。

sudo systemctl stop otelcol-contrib && sudo systemctl disable otelcol-contrib

Ninja: Open Telemetry Collector Builder (ocb) を使用して独自の Collector をビルドする

このパートでは、システムに以下がインストールされている必要があります

  • Golang(最新バージョン)

    cd /tmp
    wget https://golang.org/dl/go1.20.linux-amd64.tar.gz
    sudo tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz

    .profile を編集して、以下の環境変数を追加します

    export GOROOT=/usr/local/go
    export GOPATH=$HOME/go
    export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

    シェルセッションを更新します

    source ~/.profile

    Go のバージョンを確認します

    go version
  • ocb のインストール

    • プロジェクトリリースから ocb バイナリをダウンロードし、以下のコマンドを実行します

      mv ocb_0.80.0_darwin_arm64 /usr/bin/ocb
      chmod 755 /usr/bin/ocb

      別の方法として、golang ツールチェーンを使用してローカルでバイナリをビルドすることもできます

      go install go.opentelemetry.io/collector/cmd/builder@v0.80.0
      mv $(go env GOPATH)/bin/builder /usr/bin/ocb
  • (オプション)Docker

なぜ独自の Collector をビルドするのか?

Collector のデフォルトディストリビューション(core と contrib)は、提供する機能が多すぎるか少なすぎるかのどちらかです。

また、contrib Collector を本番環境で実行することは推奨されません。これは、インストールされるコンポーネントの量が多く、そのほとんどがデプロイメントに必要ないためです。

独自の Collector をビルドするメリットは?

独自の Collector バイナリ(一般的にディストリビューションと呼ばれる)を作成することは、必要なものだけをビルドすることを意味します。

これには以下のメリットがあります

  1. より小さなサイズのバイナリ
  2. 脆弱性に対して既存の Go スキャナーを使用できる
  3. 組織と連携できる内部コンポーネントを含めることができる

Collector をビルドする際の考慮事項は?

さて、いくつかのデメリットがなければ 🥷 Ninja ゾーンとは言えません

  1. Go の経験が推奨される(必須ではないが)
  2. Splunk サポートなし
  3. ディストリビューションとライフサイクル管理の責任

プロジェクトは安定性に向けて取り組んでいますが、変更によってワークフローが壊れないとは限らないことに注意することが重要です。Splunk のチームは、より高いサポートと安定性を提供しており、デプロイメントのニーズに応じたキュレーションされた体験を提供できます。

Ninja ゾーン

必要なツールがすべてインストールされたら、otelcol-builder.yaml という名前の新しいファイルを作成し、以下のディレクトリ構造に従います

.
└── otelcol-builder.yaml

ファイルを作成したら、いくつかの追加メタデータとともにインストールするコンポーネントのリストを追加する必要があります。

この例では、入門用の設定に必要なコンポーネントのみをインストールするビルダーマニフェストを作成します

dist:
  name: otelcol-ninja
  description: A custom build of the Open Telemetry Collector
  output_path: ./dist

extensions:
- gomod: go.opentelemetry.io/collector/extension/ballastextension v0.80.0
- gomod: go.opentelemetry.io/collector/extension/zpagesextension  v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/httpforwarder v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.80.0

exporters:
- gomod: go.opentelemetry.io/collector/exporter/loggingexporter v0.80.0
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/signalfxexporter v0.80.0

processors:
- gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.80.0
- gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.80.0

receivers:
- gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.80.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.80.0

yaml ファイルが ocb 用に更新されたら、以下のコマンドを実行します

ocb --config=otelcol-builder.yaml

これにより、以下のディレクトリ構造が作成されます

├── dist
│   ├── components.go
│   ├── components_test.go
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   ├── main_others.go
│   ├── main_windows.go
│   └── otelcol-ninja
└── otelcol-builder.yaml

参考資料

  1. https://opentelemetry.io/docs/collector/custom-collector/

デフォルト設定

OpenTelemetry は YAML ファイルを通じて設定されます。これらのファイルには、ニーズに合わせて変更できるデフォルト設定があります。提供されるデフォルト設定を見てみましょう

cat /etc/otelcol-contrib/config.yaml
 1
 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:

exporters:
  debug:
    verbosity: detailed

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

おめでとうございます!OpenTelemetry Collector のダウンロードとインストールに成功しました。OTel Ninja への道を順調に歩んでいます。しかしまず、設定ファイルと OpenTelemetry Collector の異なるディストリビューションについて説明していきましょう。

メモ

Splunk は独自の、完全にサポートされた OpenTelemetry Collector ディストリビューションを提供しています。このディストリビューションは、Splunk GitHub リポジトリからインストールするか、Splunk Observability Cloud のウィザードを使用してコピー&ペーストするだけの簡単なインストールスクリプトを作成できます。このディストリビューションには、OpenTelemetry Collector Contrib ディストリビューションでは利用できない多くの追加機能と拡張が含まれています。

  • Splunk Distribution of the OpenTelemetry Collector は本番環境でテスト済みです。大多数のお客様が本番環境で使用しています。
  • このディストリビューションを使用するお客様は、SLA 内で Splunk の公式サポートから直接サポートを受けることができます。
  • お客様は、メトリクスとトレース収集のコア設定体験に対する将来の破壊的変更を心配することなく、Splunk Distribution of the OpenTelemetry Collector を使用または移行できます(OpenTelemetry ログ収集の設定はベータ版です)。Collector のメトリクスには破壊的変更がある可能性があります。

これから設定ファイルの各セクションを説明し、ホストメトリクスを Splunk Observability Cloud に送信するように変更していきます。

Last Modified 2026/01/23

OpenTelemetry Collector Extensions

OpenTelemetry Collector がインストールできたので、OpenTelemetry Collector の拡張機能について見ていきましょう。拡張機能はオプションであり、主にテレメトリデータの処理を伴わないタスクに使用されます。拡張機能の例としては、ヘルスモニタリング、サービスディスカバリ、データ転送などがあります。

%%{
  init:{
    "theme": "base",
    "themeVariables": {
      "primaryColor": "#ffffff",
      "clusterBkg": "#eff2fb",
      "defaultLinkColor": "#333333"
    }
  }
}%%

flowchart LR;
    style E fill:#e20082,stroke:#333,stroke-width:4px,color:#fff
    subgraph Collector
    A[OTLP] --> M(Receivers)
    B[JAEGER] --> M(Receivers)
    C[Prometheus] --> M(Receivers)
    end
    subgraph Processors
    M(Receivers) --> H(Filters, Attributes, etc)
    E(Extensions)
    end
    subgraph Exporters
    H(Filters, Attributes, etc) --> S(OTLP)
    H(Filters, Attributes, etc) --> T(JAEGER)
    H(Filters, Attributes, etc) --> U(Prometheus)
    end
Last Modified 2026/01/09

2. Extensionsのサブセクション

OpenTelemetry Collector Extensions

Health Check

拡張機能は、インストール手順で参照した同じ config.yaml ファイルで設定します。config.yaml ファイルを編集して拡張機能を設定しましょう。pprofzpages 拡張機能はデフォルトの config.yaml ファイルに既に設定されていることに注意してください。このワークショップでは、Collector のヘルス状態にアクセスできるよう、すべてのネットワークインターフェースでポートを公開するように health_check 拡張機能のみを更新します。

sudo vi /etc/otelcol-contrib/config.yaml
extensions:
  health_check:
    endpoint: 0.0.0.0:13133

Collector を起動します

otelcol-contrib --config=file:/etc/otelcol-contrib/config.yaml

この拡張機能により、OpenTelemetry Collector のステータスを確認するためにプローブできる HTTP URL が有効になります。この拡張機能は、Kubernetes で liveness プローブや readiness プローブとして使用できます。curl コマンドについて詳しく知るには、curl man page を確認してください。

新しいターミナルセッションを開き、インスタンスに SSH 接続して以下のコマンドを実行します

curl http://localhost:13133
{"status":"Server available","upSince":"2024-10-07T11:00:08.004685295+01:00","uptime":"12.56420005s"}
Last Modified 2026/01/23

OpenTelemetry Collector Extensions

Performance Profiler

Performance Profiler 拡張機能は、golang の net/http/pprof エンドポイントを有効にします。これは通常、開発者がパフォーマンスプロファイルを収集し、サービスの問題を調査するために使用されます。このワークショップではこれを扱いません

Last Modified 2026/01/09

OpenTelemetry Collector Extensions

zPages

zPages は、外部エクスポーターの代わりにインプロセスで使用できる機能です。組み込まれると、バックグラウンドでトレースとメトリクス情報を収集・集約し、リクエストされたときにウェブページでこのデータを提供します。zPages は、Collector が期待どおりに動作していることを確認するための非常に便利な診断機能です。

ServiceZ は、Collector サービスの概要と、pipelinez、extensionz、featurez の各 zPages へのクイックアクセスを提供します。このページには、ビルド情報とランタイム情報も表示されます。

サンプル URL: http://localhost:55679/debug/servicezlocalhost をご自身の環境に合わせて変更してください)。

ServiceZ ServiceZ

PipelineZ は、Collector で実行されているパイプラインに関する洞察を提供します。タイプ、データが変更されるかどうかの情報を確認でき、各パイプラインで使用されているレシーバー、プロセッサー、エクスポーターの情報も確認できます。

サンプル URL: http://localhost:55679/debug/pipelinezlocalhost をご自身の環境に合わせて変更してください)。

PipelineZ PipelineZ

ExtensionZ は、Collector でアクティブな拡張機能を表示します。

サンプル URL: http://localhost:55679/debug/extensionzlocalhost をご自身の環境に合わせて変更してください)。

ExtensionZ ExtensionZ


Ninja: storage 拡張機能でデータの耐久性を向上させる

このためには、使用しているディストリビューションに file_storage 拡張機能がインストールされていることを確認する必要があります。これは、otelcol-contrib components コマンドを実行することで確認でき、以下のような結果が表示されるはずです

# ... truncated for clarity
extensions:
  - file_storage
buildinfo:
    command: otelcol-contrib
    description: OpenTelemetry Collector Contrib
    version: 0.80.0
receivers:
    - prometheus_simple
    - apache
    - influxdb
    - purefa
    - purefb
    - receiver_creator
    - mongodbatlas
    - vcenter
    - snmp
    - expvar
    - jmx
    - kafka
    - skywalking
    - udplog
    - carbon
    - kafkametrics
    - memcached
    - prometheus
    - windowseventlog
    - zookeeper
    - otlp
    - awsecscontainermetrics
    - iis
    - mysql
    - nsxt
    - aerospike
    - elasticsearch
    - httpcheck
    - k8sobjects
    - mongodb
    - hostmetrics
    - signalfx
    - statsd
    - awsxray
    - cloudfoundry
    - collectd
    - couchdb
    - kubeletstats
    - jaeger
    - journald
    - riak
    - splunk_hec
    - active_directory_ds
    - awscloudwatch
    - sqlquery
    - windowsperfcounters
    - flinkmetrics
    - googlecloudpubsub
    - podman_stats
    - wavefront
    - k8s_events
    - postgresql
    - rabbitmq
    - sapm
    - sqlserver
    - redis
    - solace
    - tcplog
    - awscontainerinsightreceiver
    - awsfirehose
    - bigip
    - filelog
    - googlecloudspanner
    - cloudflare
    - docker_stats
    - k8s_cluster
    - pulsar
    - zipkin
    - nginx
    - opencensus
    - azureeventhub
    - datadog
    - fluentforward
    - otlpjsonfile
    - syslog
processors:
    - resource
    - batch
    - cumulativetodelta
    - groupbyattrs
    - groupbytrace
    - k8sattributes
    - experimental_metricsgeneration
    - metricstransform
    - routing
    - attributes
    - datadog
    - deltatorate
    - spanmetrics
    - span
    - memory_limiter
    - redaction
    - resourcedetection
    - servicegraph
    - transform
    - filter
    - probabilistic_sampler
    - tail_sampling
exporters:
    - otlp
    - carbon
    - datadog
    - f5cloud
    - kafka
    - mezmo
    - skywalking
    - awsxray
    - dynatrace
    - loki
    - prometheus
    - logging
    - azuredataexplorer
    - azuremonitor
    - instana
    - jaeger
    - loadbalancing
    - sentry
    - splunk_hec
    - tanzuobservability
    - zipkin
    - alibabacloud_logservice
    - clickhouse
    - file
    - googlecloud
    - prometheusremotewrite
    - awscloudwatchlogs
    - googlecloudpubsub
    - jaeger_thrift
    - logzio
    - sapm
    - sumologic
    - otlphttp
    - googlemanagedprometheus
    - opencensus
    - awskinesis
    - coralogix
    - influxdb
    - logicmonitor
    - signalfx
    - tencentcloud_logservice
    - awsemf
    - elasticsearch
    - pulsar
extensions:
    - zpages
    - bearertokenauth
    - oidc
    - host_observer
    - sigv4auth
    - file_storage
    - memory_ballast
    - health_check
    - oauth2client
    - awsproxy
    - http_forwarder
    - jaegerremotesampling
    - k8s_observer
    - pprof
    - asapclient
    - basicauth
    - headers_setter

この拡張機能は、エクスポーターが設定されたエンドポイントにデータを送信できない場合に、エクスポーターがデータをディスクにキューイングする機能を提供します。

拡張機能を設定するには、以下の情報を含めるように設定を更新する必要があります。まず、/tmp/otel-data ディレクトリを作成し、読み書き権限を付与してください

extensions:
...
  file_storage:
    directory: /tmp/otel-data
    timeout: 10s
    compaction:
      directory: /tmp/otel-data
      on_start: true
      on_rebound: true
      rebound_needed_threshold_mib: 5
      rebound_trigger_threshold_mib: 3

# ... truncated for clarity

service:
  extensions: [health_check, pprof, zpages, file_storage]

なぜデータをディスクにキューイングするのか?

これにより、Collector はネットワークの中断(さらには Collector の再起動)を乗り越えて、データがアップストリームプロバイダーに送信されることを保証できます。

データをディスクにキューイングする際の考慮事項

ディスクのパフォーマンスにより、データスループットのパフォーマンスに影響を与える可能性があります。

参考資料

  1. https://community.splunk.com/t5/Community-Blog/Data-Persistence-in-the-OpenTelemetry-Collector/ba-p/624583
  2. https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/storage/filestorage

設定の確認

拡張機能について学んだので、設定の変更を確認しましょう。


Check-in設定を確認する
 1
 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:

exporters:
  debug:
    verbosity: detailed

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

拡張機能について確認したので、次はワークショップのデータパイプライン部分に進みましょう。パイプラインは、Collector 内でデータが辿る経路を定義し、受信から始まり、さらなる処理や変更を経て、最終的にエクスポーターを通じて Collector を出ていきます。

OpenTelemetry Collector のデータパイプラインは、レシーバープロセッサーエクスポーターで構成されています。まずはレシーバーから始めます。

Last Modified 2026/01/23

OpenTelemetry Collector Receivers

ワークショップの Receiver セクションへようこそ!ここは OpenTelemetry Collector のデータパイプラインの出発点です。早速始めましょう。

Receiver は、プッシュベースまたはプルベースであり、データを Collector に取り込む方法です。Receiver は1つ以上のデータソースをサポートできます。一般的に、Receiver は指定された形式でデータを受け取り、内部形式に変換してから、該当するパイプラインで定義された Processor と Exporter に渡します。

%%{
  init:{
    "theme":"base",
    "themeVariables": {
      "primaryColor": "#ffffff",
      "clusterBkg": "#eff2fb",
      "defaultLinkColor": "#333333"
    }
  }
}%%

flowchart LR;
    style M fill:#e20082,stroke:#333,stroke-width:4px,color:#fff
    subgraph Collector
    A[OTLP] --> M(Receivers)
    B[JAEGER] --> M(Receivers)
    C[Prometheus] --> M(Receivers)
    end
    subgraph Processors
    M(Receivers) --> H(Filters, Attributes, etc)
    E(Extensions)
    end
    subgraph Exporters
    H(Filters, Attributes, etc) --> S(OTLP)
    H(Filters, Attributes, etc) --> T(JAEGER)
    H(Filters, Attributes, etc) --> U(Prometheus)
    end
Last Modified 2026/01/09

3. Receiversのサブセクション

OpenTelemetry Collector Receivers

Host Metrics Receiver

Host Metrics Receiver は、さまざまなソースからスクレイピングしたホストシステムに関するメトリクスを生成します。これは、Collector がエージェントとしてデプロイされる場合に使用することを想定しており、このワークショップでもその方法を採用します。

/etc/otel-contrib/config.yaml ファイルを更新して、hostmetrics Receiver を設定しましょう。以下の YAML を receivers セクションの下に挿入してください。インデントはスペース2つで行います。

sudo vi /etc/otelcol-contrib/config.yaml
receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      # CPU utilization metrics
      cpu:
      # Disk I/O metrics
      disk:
      # File System utilization metrics
      filesystem:
      # Memory utilization metrics
      memory:
      # Network interface I/O metrics & TCP connection metrics
      network:
      # CPU load metrics
      load:
      # Paging/Swap space utilization and I/O metrics
      paging:
      # Process count metrics
      processes:
      # Per process CPU, Memory and Disk I/O metrics. Disabled by default.
      # process:
Last Modified 2026/01/09

OpenTelemetry Collector Receivers

Prometheus Receiver

prometheus という別の Receiver があることにも気づくでしょう。Prometheus は、OpenTelemetry Collector が使用するオープンソースのツールキットです。この Receiver は、OpenTelemetry Collector 自体からメトリクスをスクレイピングするために使用されます。これらのメトリクスは、Collector の健全性を監視するために使用できます。

prometheus Receiver を変更して、Collector 自体からメトリクスを収集するためのものであることを明確にしましょう。Receiver の名前を prometheus から prometheus/internal に変更することで、その Receiver が何をしているかがより明確になります。設定ファイルを以下のように更新してください

prometheus/internal:
  config:
    scrape_configs:
    - job_name: 'otel-collector'
      scrape_interval: 10s
      static_configs:
      - targets: ['0.0.0.0:8888']

ダッシュボード例 - Prometheus メトリクス

以下のスクリーンショットは、Prometheus internal Receiver が OpenTelemetry Collector から収集するメトリクスの一部を表示するダッシュボード例です。ここでは、受け入れられたスパン、メトリクス、ログレコードと送信されたものを確認できます。

メモ

以下のスクリーンショットは、Splunk Observability Cloud の標準(OOTB)ダッシュボードで、Splunk OpenTelemetry Collector のインストール状況を簡単に監視できます。

otel-charts otel-charts

Last Modified 2026/01/23

OpenTelemetry Collector Receivers

その他の Receiver

デフォルト設定には、otlpopencensusjaegerzipkin などの他の Receiver があることに気づくでしょう。これらは他のソースからテレメトリデータを受信するために使用されます。このワークショップではこれらの Receiver については取り上げませんので、そのままにしておいてください。


Ninja: Receiver を動的に作成する

Docker コンテナ、Kubernetes Pod、SSH セッションなどの短期間のタスクを監視するために、receiver creatorobserver extensions を使用して、これらのサービスが起動するときに新しい Receiver を作成できます。

何が必要ですか?

receiver creator とそれに関連する observer extension を使い始めるには、それらが Collector のビルドマニフェストに含まれている必要があります。

詳細は installation を参照してください。

考慮すべき事項

一部の短期間のタスクでは、usernamepassword などの追加設定が必要な場合があります。 これらの値は 環境変数 で参照するか、 ${file:./path/to/database/password} のようなスキーム展開構文を使用できます。 この方法を採用する場合は、組織のシークレット管理のベストプラクティスに従ってください。

Ninja ゾーン

この Ninja ゾーンに必要なことは2つだけです

  1. ビルダーマニフェストに receiver creator と observer extension が追加されていることを確認します。
  2. 検出されたエンドポイントとマッチングするために使用できる設定を作成します。

テンプレート化された設定を作成するには、以下のようにします

receiver_creator:
  watch_observers: [host_observer]
  receivers:
    redis:
      rule: type == "port" && port == 6379
      config:
        password: ${env:HOST_REDIS_PASSWORD}

その他の例については、receiver creator の例 を参照してください。


設定の確認

Receiver について説明しましたので、設定の変更を確認しましょう。


Check-in設定を確認する
 1
 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      # CPU utilization metrics
      cpu:
      # Disk I/O metrics
      disk:
      # File System utilization metrics
      filesystem:
      # Memory utilization metrics
      memory:
      # Network interface I/O metrics & TCP connection metrics
      network:
      # CPU load metrics
      load:
      # Paging/Swap space utilization and I/O metrics
      paging:
      # Process count metrics
      processes:
      # Per process CPU, Memory and Disk I/O metrics. Disabled by default.
      # process:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus/internal:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:

exporters:
  debug:
    verbosity: detailed

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

Receiver を通じてデータが OpenTelemetry Collector にどのように取り込まれるかを確認しました。次は、Collector が受信したデータをどのように処理するかを見ていきましょう。

警告

/etc/otelcol-contrib/config.yaml はまだ完成していないため、この時点では Collector を再起動しないでください

Last Modified 2026/01/23

OpenTelemetry Collector Processors

Processors は、データを受信してからエクスポートするまでの間に実行されます。Processors はオプションですが、一部は推奨されています。OpenTelemetry contrib Collector には 多数の Processors が含まれています。

%%{
  init:{
    "theme":"base",
    "themeVariables": {
      "primaryColor": "#ffffff",
      "clusterBkg": "#eff2fb",
      "defaultLinkColor": "#333333"
    }
  }
}%%

flowchart LR;
    style Processors fill:#e20082,stroke:#333,stroke-width:4px,color:#fff
    subgraph Collector
    A[OTLP] --> M(Receivers)
    B[JAEGER] --> M(Receivers)
    C[Prometheus] --> M(Receivers)
    end
    subgraph Processors
    M(Receivers) --> H(Filters, Attributes, etc)
    E(Extensions)
    end
    subgraph Exporters
    H(Filters, Attributes, etc) --> S(OTLP)
    H(Filters, Attributes, etc) --> T(JAEGER)
    H(Filters, Attributes, etc) --> U(Prometheus)
    end
Last Modified 2026/01/09

4. Processorsのサブセクション

OpenTelemetry Collector Processors

Batch Processor

デフォルトでは、batch processor のみが有効になっています。この processor は、データをエクスポートする前にバッチ処理するために使用されます。これは、exporter へのネットワーク呼び出しの回数を減らすのに役立ちます。このワークショップでは、Collector にハードコードされている以下のデフォルト値を継承します

  • send_batch_size(デフォルト = 8192):タイムアウトに関係なくバッチが送信されるスパン、メトリクスデータポイント、またはログレコードの数。send_batch_size はトリガーとして機能し、バッチのサイズには影響しません。パイプラインの次のコンポーネントに送信されるバッチサイズの制限を強制する必要がある場合は、send_batch_max_size を参照してください。
  • timeout(デフォルト = 200ms):サイズに関係なくバッチが送信されるまでの時間。ゼロに設定すると、send_batch_max_size のみに従ってデータが即座に送信されるため、send_batch_size は無視されます。
  • send_batch_max_size(デフォルト = 0):バッチサイズの上限。0 はバッチサイズに上限がないことを意味します。このプロパティは、大きなバッチを小さな単位に分割することを保証します。send_batch_size 以上である必要があります。

Batch processor の詳細については、Batch Processor のドキュメントを参照してください。

Last Modified 2026/01/23

OpenTelemetry Collector Processors

Resource Detection Processor

resourcedetection processor は、ホストからリソース情報を検出し、テレメトリデータのリソース値にこの情報を追加または上書きするために使用できます。

デフォルトでは、ホスト名は可能であれば FQDN に設定され、それ以外の場合は OS が提供するホスト名がフォールバックとして使用されます。このロジックは hostname_sources 設定オプションを使用して変更できます。FQDN を取得せずに OS が提供するホスト名を使用するには、hostname_sourcesos に設定します。

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]

ワークショップインスタンスが AWS/EC2 インスタンスで実行されている場合、EC2 メタデータ API から以下のタグを収集できます(これは他のプラットフォームでは利用できません)。

  • cloud.provider ("aws")
  • cloud.platform ("aws_ec2")
  • cloud.account.id
  • cloud.region
  • cloud.availability_zone
  • host.id
  • host.image.id
  • host.name
  • host.type

これらのタグをメトリクスに追加するために、別の processor を作成します。

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]
  resourcedetection/ec2:
    detectors: [ec2]
Last Modified 2026/01/09

OpenTelemetry Collector Processors

Attributes Processor

attributes processor は、スパン、ログ、またはメトリクスの属性を変更します。この processor は、指定されたアクションに含めるか除外するかを決定するために、入力データをフィルタリングおよびマッチングする機能もサポートしています。

設定で指定された順序で実行されるアクションのリストを受け取ります。サポートされているアクションは以下の通りです

  • insert:キーがまだ存在しない入力データに新しい属性を挿入します。
  • update:キーが存在する入力データの属性を更新します。
  • upsert:insert または update を実行します。キーがまだ存在しない入力データに新しい属性を挿入し、キーが存在する入力データの属性を更新します。
  • delete:入力データから属性を削除します。
  • hash:既存の属性値をハッシュ化(SHA1)します。
  • extract:正規表現ルールを使用して入力キーからルールで指定されたターゲットキーに値を抽出します。ターゲットキーがすでに存在する場合は上書きされます。

すべてのホストメトリクスに participant.name という新しい属性を insert する attributes processor を作成します。値にはあなたの名前(例:marge_simpson)を設定します。

警告

INSERT_YOUR_NAME_HERE を必ずあなたの名前に置き換えてください。また、名前にスペースを使用しないようにしてください。

ワークショップの後半で、Splunk Observability Cloud でメトリクスをフィルタリングするためにこの属性を使用します。

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]
  resourcedetection/ec2:
    detectors: [ec2]
  attributes/conf:
    actions:
      - key: participant.name
        action: insert
        value: "INSERT_YOUR_NAME_HERE"

Ninja: connector を使用して内部インサイトを取得する

Collector への最新の追加機能の1つは connector の概念で、あるパイプラインの出力を別のパイプラインの入力に接続できます。

これが有益な例として、一部のサービスはエクスポートされるデータポイントの量、エラーステータスを含むログの数、または特定のデプロイ環境から送信されるデータ量に基づいてメトリクスを出力します。count connector はこれをすぐに使える形で対処するのに役立ちます。

processor の代わりに connector を使用する理由

processor は処理したデータを渡す必要があるため、追加データを生成する点で制限があり、追加情報を公開するのが困難です。connector は受信したデータを出力する必要がないため、求めているインサイトを作成する機会を提供します。

例えば、デプロイ環境属性を持たないログ、メトリクス、トレースの数をカウントする connector を作成できます。

デプロイ環境別にデータ使用量を分類できる非常にシンプルな例です。

connector に関する考慮事項

connector は、あるパイプラインからエクスポートされ、別のパイプラインで受信されたデータのみを受け入れます。これは、connector を活用するために Collector の設定をどのように構成するかを検討する必要があることを意味します。

参考資料

  1. https://opentelemetry.io/docs/collector/configuration/#connectors
  2. https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/countconnector

設定の確認

processors について説明しました。設定の変更を確認しましょう。


Check-in設定を確認する
  1
  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
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      # CPU utilization metrics
      cpu:
      # Disk I/O metrics
      disk:
      # File System utilization metrics
      filesystem:
      # Memory utilization metrics
      memory:
      # Network interface I/O metrics & TCP connection metrics
      network:
      # CPU load metrics
      load:
      # Paging/Swap space utilization and I/O metrics
      paging:
      # Process count metrics
      processes:
      # Per process CPU, Memory and Disk I/O metrics. Disabled by default.
      # process:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus/internal:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]
  resourcedetection/ec2:
    detectors: [ec2]
  attributes/conf:
    actions:
      - key: participant.name
        action: insert
        value: "INSERT_YOUR_NAME_HERE"

exporters:
  debug:
    verbosity: detailed

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

Last Modified 2026/01/23

OpenTelemetry Collector Exporters

Exporter はプッシュ型またはプル型で、1つ以上のバックエンド/宛先にデータを送信する方法です。Exporter は1つ以上のデータソースをサポートする場合があります。

このワークショップでは、otlphttp exporter を使用します。OpenTelemetry Protocol (OTLP) は、テレメトリデータを送信するためのベンダー中立で標準化されたプロトコルです。OTLP exporter は、OTLP プロトコルを実装しているサーバーにデータを送信します。OTLP exporter は gRPCHTTP/JSON の両方のプロトコルをサポートしています。

%%{
  init:{
    "theme":"base",
    "themeVariables": {
      "primaryColor": "#ffffff",
      "clusterBkg": "#eff2fb",
      "defaultLinkColor": "#333333"
    }
  }
}%%

flowchart LR;
    style Exporters fill:#e20082,stroke:#333,stroke-width:4px,color:#fff
    subgraph Collector
    A[OTLP] --> M(Receivers)
    B[JAEGER] --> M(Receivers)
    C[Prometheus] --> M(Receivers)
    end
    subgraph Processors
    M(Receivers) --> H(Filters, Attributes, etc)
    E(Extensions)
    end
    subgraph Exporters
    H(Filters, Attributes, etc) --> S(OTLP)
    H(Filters, Attributes, etc) --> T(JAEGER)
    H(Filters, Attributes, etc) --> U(Prometheus)
    end
Last Modified 2026/01/09

5. Exportersのサブセクション

OpenTelemetry Collector Exporters

OTLP HTTP Exporter

HTTP 経由で Splunk Observability Cloud にメトリクスを送信するには、otlphttp exporter を設定する必要があります。

/etc/otelcol-contrib/config.yaml ファイルを編集して、otlphttp exporter を設定しましょう。以下の YAML を exporters セクションの下に挿入してください。インデントは2スペースで行ってください。

また、ディスクがいっぱいにならないように、logging exporter の詳細度を変更します。デフォルトの detailed は非常に冗長です。

exporters:
  logging:
    verbosity: normal
  otlphttp/splunk:

次に、metrics_endpoint を定義してターゲット URL を設定する必要があります。

メモ

Splunk 主催のワークショップに参加されている場合、使用しているインスタンスにはすでに Realm 環境変数が設定されています。設定ファイルでその環境変数を参照します。それ以外の場合は、新しい環境変数を作成して Realm を設定する必要があります。例

export REALM="us1"

使用する URL は https://ingest.${env:REALM}.signalfx.com/v2/datapoint/otlp です。(Splunk は、データレジデンシーのために世界中の主要な地理的場所に Realm を持っています)。

otlphttp exporter は、traces_endpointlogs_endpoint のターゲット URL を定義することで、トレースとログを送信するように設定することもできます。これらの設定は、このワークショップの範囲外です。

exporters:
  logging:
    verbosity: normal
  otlphttp/splunk:
    metrics_endpoint: https://ingest.${env:REALM}.signalfx.com/v2/datapoint/otlp

デフォルトでは、すべてのエンドポイントで gzip 圧縮が有効になっています。これは、exporter 設定で compression: none を設定することで無効にできます。このワークショップでは、データを送信する最も効率的な方法であるため、圧縮を有効のままにしてデフォルトを使用します。

Splunk Observability Cloud にメトリクスを送信するには、アクセストークンを使用する必要があります。これは、Splunk Observability Cloud UI で新しいトークンを作成することで行えます。トークンの作成方法の詳細については、Create a token を参照してください。トークンは INGEST タイプである必要があります。

メモ

Splunk 主催のワークショップに参加されている場合、使用しているインスタンスにはすでにアクセストークンが設定されています(環境変数として設定されています)。設定ファイルでその環境変数を参照します。それ以外の場合は、新しいトークンを作成して環境変数として設定する必要があります。例

export ACCESS_TOKEN=<replace-with-your-token>

トークンは、headers: セクションの下に X-SF-TOKEN: ${env:ACCESS_TOKEN} を挿入することで設定ファイルに定義されます

exporters:
  logging:
    verbosity: normal
  otlphttp/splunk:
    metrics_endpoint: https://ingest.${env:REALM}.signalfx.com/v2/datapoint/otlp
    headers:
      X-SF-TOKEN: ${env:ACCESS_TOKEN}

設定の確認

Exporter について説明したので、設定の変更を確認しましょう


Check-inReview your configuration
  1
  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
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      # CPU utilization metrics
      cpu:
      # Disk I/O metrics
      disk:
      # File System utilization metrics
      filesystem:
      # Memory utilization metrics
      memory:
      # Network interface I/O metrics & TCP connection metrics
      network:
      # CPU load metrics
      load:
      # Paging/Swap space utilization and I/O metrics
      paging:
      # Process count metrics
      processes:
      # Per process CPU, Memory and Disk I/O metrics. Disabled by default.
      # process:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus/internal:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]
  resourcedetection/ec2:
    detectors: [ec2]
  attributes/conf:
    actions:
      - key: participant.name
        action: insert
        value: "INSERT_YOUR_NAME_HERE"

exporters:
  debug:
    verbosity: normal
  otlphttp/splunk:
    metrics_endpoint: https://ingest.${env:REALM}.signalfx.com/v2/datapoint/otlp
    headers:
      X-SF-Token: ${env:ACCESS_TOKEN}

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

もちろん、OTLP プロトコルをサポートする他のソリューションを指すように metrics_endpoint を簡単に設定できます。

次に、config.yaml の service セクションで、設定した receivers、processors、exporters を有効にする必要があります。

Last Modified 2026/01/23

OpenTelemetry Collector Service

Service セクションは、receivers、processors、exporters、extensions セクションで定義された設定に基づいて、Collector でどのコンポーネントを有効にするかを設定するために使用します。

情報

コンポーネントが設定されていても、Service セクション内で定義されていない場合、そのコンポーネントは有効になりません

service セクションは3つのサブセクションで構成されています

  • extensions
  • pipelines
  • telemetry

デフォルト設定では、extension セクションは health_checkpprofzpages を有効にするよう設定されています。これらは先ほど Extensions モジュールで設定しました。

service:
  extensions: [health_check, pprof, zpages]

それでは、Metric Pipeline を設定しましょう!

Last Modified 2026/01/23

6. Serviceのサブセクション

OpenTelemetry Collector Service

Hostmetrics Receiver

ワークショップの Receivers セクションで、さまざまなソースからスクレイプされるホストシステムに関するメトリクスを生成する Host Metrics Receiver を定義したことを思い出してください。この receiver を有効にするには、metrics パイプラインに hostmetrics receiver を含める必要があります。

metrics パイプラインで、metrics の receivers セクションに hostmetrics を追加します。

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]
Last Modified 2026/01/09

OpenTelemetry Collector Service

Prometheus Internal Receiver

ワークショップの前半で、Collector 内部のメトリクスを収集していることを反映するために prometheus receiver の名前を prometheus/internal に変更しました。

ここで、metrics パイプラインで prometheus/internal receiver を有効にする必要があります。metrics パイプラインの receivers セクションに prometheus/internal を含めるように更新します

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus/internal]
      processors: [batch]
      exporters: [debug]
Last Modified 2026/01/23

OpenTelemetry Collector Service

Resource Detection Processor

また、Collector がインスタンスのホスト名と AWS/EC2 メタデータをキャプチャできるように、resourcedetection/systemresourcedetection/ec2 processor を追加しました。ここで、metrics パイプラインでこれら2つの processor を有効にする必要があります。

metrics パイプラインの processors セクションに resourcedetection/systemresourcedetection/ec2 を含めるように更新します

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus/internal]
      processors: [batch, resourcedetection/system, resourcedetection/ec2]
      exporters: [debug]
Last Modified 2026/01/23

OpenTelemetry Collector Service

Attributes Processor

また、このワークショップの Processors セクションで、Collector がすべてのメトリクスに participant.name という新しい属性を挿入するように attributes/conf processor を追加しました。ここで、metrics パイプラインでこれを有効にする必要があります。

metrics パイプラインの processors セクションに attributes/conf を含めるように更新します

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus/internal]
      processors: [batch, resourcedetection/system, resourcedetection/ec2, attributes/conf]
      exporters: [debug]
Last Modified 2026/01/23

OpenTelemetry Collector Service

OTLP HTTP Exporter

ワークショップの Exporters セクションで、メトリクスを Splunk Observability Cloud に送信するための otlphttp exporter を設定しました。ここで、metrics パイプラインでこれを有効にする必要があります。

metrics パイプラインの exporters セクションに otlphttp/splunk を含めるように更新します

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus/internal]
      processors: [batch, resourcedetection/system, resourcedetection/ec2, attributes/conf]
      exporters: [debug, otlphttp/splunk]

Ninja: Collector の内部を観察する

Collector は、実行中のコンポーネントからの追加シグナルを含む、自身の動作に関する内部シグナルをキャプチャします。 これは、データフローに関する判断を行うコンポーネントが、その情報をメトリクスまたはトレースとして公開する方法を必要とするためです。

なぜ Collector を監視するのか?

これは「監視者を誰が監視するのか?」という、鶏と卵のような問題ですが、この情報を公開できることは重要です。Collector の歴史において興味深い点は、Go メトリクス SDK が安定版と見なされる前から存在していたため、当面の間、Collector はこの機能を提供するために Prometheus エンドポイントを公開しているということです。

考慮事項

組織内で実行中の各 Collector の内部使用状況を監視すると、大量の新しい Metric Time Series (MTS) が発生する可能性があります。Splunk ディストリビューションでは、これらのメトリクスが厳選されており、予想される増加を予測するのに役立ちます。

Ninja Zone

Collector の内部オブザーバビリティを公開するために、いくつかの追加設定を調整できます

service:
  telemetry:
    logs:
      level: <info|warn|error>
      development: <true|false>
      encoding: <console|json>
      disable_caller: <true|false>
      disable_stacktrace: <true|false>
      output_paths: [<stdout|stderr>, paths...]
      error_output_paths: [<stdout|stderr>, paths...]
      initial_fields:
        key: value
    metrics:
      level: <none|basic|normal|detailed>
      # Address binds the promethues endpoint to scrape
      address: <hostname:port>
service:
  telemetry:
    logs:
      level: info
      encoding: json
      disable_stacktrace: true
      initial_fields:
        instance.name: ${env:INSTANCE}
    metrics:
      address: localhost:8888

参考資料

  1. https://opentelemetry.io/docs/collector/configuration/#service

最終設定


Check-in最終設定を確認する
  1
  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
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
# To limit exposure to denial of service attacks, change the host in endpoints below from 0.0.0.0 to a specific network interface.
# See https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      # CPU utilization metrics
      cpu:
      # Disk I/O metrics
      disk:
      # File System utilization metrics
      filesystem:
      # Memory utilization metrics
      memory:
      # Network interface I/O metrics & TCP connection metrics
      network:
      # CPU load metrics
      load:
      # Paging/Swap space utilization and I/O metrics
      paging:
      # Process count metrics
      processes:
      # Per process CPU, Memory and Disk I/O metrics. Disabled by default.
      # process:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus/internal:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:
  resourcedetection/system:
    detectors: [system]
    system:
      hostname_sources: [os]
  resourcedetection/ec2:
    detectors: [ec2]
  attributes/conf:
    actions:
      - key: participant.name
        action: insert
        value: "INSERT_YOUR_NAME_HERE"

exporters:
  debug:
    verbosity: normal
  otlphttp/splunk:
    metrics_endpoint: https://ingest.${env:REALM}.signalfx.com/v2/datapoint/otlp
    headers:
      X-SF-Token: ${env:ACCESS_TOKEN}

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [debug]

    metrics:
      receivers: [hostmetrics, otlp, opencensus, prometheus/internal]
      processors: [batch, resourcedetection/system, resourcedetection/ec2, attributes/conf]
      exporters: [debug, otlphttp/splunk]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

  extensions: [health_check, pprof, zpages]

ヒント

Collector を再起動する前に、設定ファイルを検証することをお勧めします。config.yaml ファイルの内容を otelbin.io に貼り付けることで検証できます。

ScreenshotOTelBin

otelbin-validator otelbin-validator

これで動作する設定ができたので、Collector を起動して zPages が何を報告しているか確認しましょう。

otelcol-contrib --config=file:/etc/otelcol-contrib/config.yaml

ブラウザで zPages を開きます:http://localhost:55679/debug/pipelinezlocalhost を自分の環境に合わせて変更してください)。 pipelinez-full-config pipelinez-full-config

Last Modified 2026/01/23

データの可視化

Splunk Observability Cloud

OpenTelemetry Collector からメトリクスを Splunk Observability Cloud に送信する設定が完了したので、Splunk Observability Cloud でデータを確認してみましょう。Splunk Observability Cloud への招待を受け取っていない場合は、インストラクターがログイン資格情報を提供します。

その前に、少し面白くするためにインスタンスでストレステストを実行してみましょう。これによりダッシュボードが活性化されます。

sudo apt install stress
while true; do stress -c 2 -t 40; stress -d 5 -t 40; stress -m 20 -t 40; done

Splunk Observability Cloud にログインしたら、左側のナビゲーションを使用してメインメニューから Dashboards に移動します。これによりチームビューが表示されます。このビューの上部にある All Dashboards をクリックします

menu-dashboards menu-dashboards

検索ボックスで OTel Contrib を検索します

search-dashboards search-dashboards

情報

ダッシュボードが存在しない場合は、インストラクターがすぐに追加できます。Splunk 主催のワークショップに参加していない場合は、インポートするダッシュボードグループをこのページの下部で見つけることができます。

OTel Contrib Dashboard ダッシュボードをクリックして開き、次にダッシュボード上部の Participant Name ボックスをクリックして、config.yamlparticipant.name に設定した名前をドロップダウンリストから選択するか、名前を入力して検索します

select-conf-attendee-name select-conf-attendee-name

これで、OpenTelemetry Collector を設定したホストのホストメトリクスを確認できます。

participant-dashboard participant-dashboard

Download Dashboard Group JSON for importing
Last Modified 2026/01/23

OpenTelemetry Collector 開発

カスタムコンポーネントの開発

OpenTelemetry Collector 用のコンポーネントを構築するには、3つの主要な部分が必要です

  1. Configuration - ユーザーに公開される設定値
  2. Factory - 提供された値を使用してコンポーネントを作成する
  3. Business Logic - コンポーネントが実行する必要がある処理

ここでは、プロジェクトの重要な DevOps メトリクスを追跡できるように、Jenkins と連携するコンポーネントを構築する例を使用します。

測定しようとしているメトリクスは以下の通りです

  1. Lead time for changes - “コミットが本番環境にデプロイされるまでにかかる時間”
  2. Change failure rate - “本番環境で障害を引き起こすデプロイメントの割合”
  3. Deployment frequency - "[チーム]が本番環境に正常にリリースする頻度"
  4. Mean time to recover - "[チーム]が本番環境の障害から復旧するまでにかかる時間"

これらの指標は、ソフトウェア開発チームのパフォーマンスを示すために、Google の DevOps Research and Assessment(DORA)[^1] チームによって特定されました。Jenkins CI を選択した理由は、同じオープンソースソフトウェアのエコシステム内にとどまることで、将来ベンダーが管理する CI ツールが採用するための例として機能できるからです。

計装 vs コンポーネント

組織内のオブザーバビリティのレベルを向上させる際に考慮すべきことがあります。いくつかのトレードオフが生じるためです。

メリットデメリット
(自動)計装システムを監視するために外部 API を監視する必要がありません。計装を変更するにはプロジェクトへの変更が必要です。
システムオーナー/開発者がオブザーバビリティを変更する権限を持てます。追加のランタイム依存関係が必要です。
システムコンテキストを理解し、キャプチャしたデータを Exemplars と関連付けることができます。システムのパフォーマンスに影響を与える可能性があります。
コンポーネントデータ名やセマンティクスへの変更をシステムのリリースサイクルとは独立して展開できます。API の破壊的な変更には、システムと Collector の間で調整されたリリースが必要です。
収集されるデータの更新/拡張は、ユーザーにとってシームレスな変更です。キャプチャされたデータのセマンティクスが、新しいシステムリリースと一致しない形で予期せず壊れる可能性があります。
サポートチームがオブザーバビリティの実践について深い理解を持つ必要がありません。システムから外部に公開された情報のみを表面化できます。
Last Modified 2026/01/23

8. Developのサブセクション

OpenTelemetry Collector 開発

プロジェクトのセットアップ Ninja

メモ

このワークショップセクションを完了するまでの時間は、経験によって異なります。

行き詰まった場合やインストラクターに沿って進めたい場合は、こちらに完全なソリューションがあります。

新しい Jenkins CI レシーバーの開発を始めるには、まず Golang プロジェクトをセットアップする必要があります。 新しい Golang プロジェクトを作成する手順は以下の通りです

  1. ${HOME}/go/src/jenkinscireceiver という名前の新しいディレクトリを作成し、そのディレクトリに移動します
    1. 実際のディレクトリ名や場所は厳密ではなく、独自の開発ディレクトリを選択して作成できます。
  2. go mod init splunk.conf/workshop/example/jenkinscireceiver を実行して golang モジュールを初期化します
    1. これにより go.mod というファイルが作成され、直接的および間接的な依存関係を追跡するために使用されます
    2. 最終的には、インポートされる依存関係のチェックサム値である go.sum が生成されます。
Check-ingo.mod を確認する
module splunk.conf/workshop/example/jenkinscireceiver

go 1.20
Last Modified 2026/01/23

OpenTelemetry Collector 開発

Configuration の構築

コンポーネントの Configuration 部分は、ユーザーがコンポーネントに対して入力を行う方法です。そのため、設定に使用される値は以下の条件を満たす必要があります

  1. そのフィールドが何を制御するかをユーザーが直感的に理解できること
  2. 必須と任意を明確にすること
  3. 一般的な名前とフィールドを再利用すること
  4. オプションをシンプルに保つこと
---
jenkins_server_addr: hostname
jenkins_server_api_port: 8089
interval: 10m
filter_builds_by:
    - name: my-awesome-build
      status: amber
track:
    values:
        example.metric.1: yes
        example.metric.2: yes
        example.metric.3: no
        example.metric.4: no
---
# Required Values
endpoint: http://my-jenkins-server:8089
auth:
    authenticator: basicauth/jenkins
# Optional Values
collection_interval: 10m
metrics:
    example.metric.1:
        enabled: true
    example.metric.2:
        enabled: true
    example.metric.3:
        enabled: true
    example.metric.4:
        enabled: true

悪い設定例は、設定のベストプラクティスの逆を行うことがコンポーネントの使いやすさにどのように影響するかを示しています。フィールド値が何であるべきかが明確ではなく、既存のプロセッサにプッシュできる機能が含まれており、フィールド名が Collector に存在する他のコンポーネントと一貫していません。

良い設定例は、必須の値をシンプルに保ち、他のコンポーネントからフィールド名を再利用し、コンポーネントが Jenkins と Collector 間の相互作用のみに焦点を当てることを確保しています。

コードタブは、私たちが追加する必要がある量と、Collector 内の共有ライブラリによってすでに提供されているものを示しています。これらはビジネスロジックに到達したときにより詳細に説明します。Configuration は小さく始まり、追加機能が必要になるとビジネスロジックが含まれるようになると変更されます。

コードを書く

Configuration に必要なコードを実装するために、以下の内容で config.go という新しいファイルを作成します

package jenkinscireceiver

import (
    "go.opentelemetry.io/collector/config/confighttp"
    "go.opentelemetry.io/collector/receiver/scraperhelper"

    "splunk.conf/workshop/example/jenkinscireceiver/internal/metadata"
)

type Config struct {
    // HTTPClientSettings contains all the values
    // that are commonly shared across all HTTP interactions
    // performed by the collector.
    confighttp.HTTPClientSettings `mapstructure:",squash"`
    // ScraperControllerSettings will allow us to schedule
    // how often to check for updates to builds.
    scraperhelper.ScraperControllerSettings `mapstructure:",squash"`
    // MetricsBuilderConfig contains all the metrics
    // that can be configured.
    metadata.MetricsBuilderConfig `mapstructure:",squash"`
}
Last Modified 2026/01/23

OpenTelemetry Collector 開発

コンポーネントのレビュー

Jenkins からメトリクスをキャプチャするために必要なコンポーネントの種類を振り返ります

Extension が解決するビジネスユースケースは以下の通りです

  1. ランタイム設定が必要な共有機能を持つこと
  2. Collector のランタイムを観測することを間接的に支援すること

詳細は Extensions の概要 を参照してください。

Receiver が解決するビジネスユースケースは以下の通りです

  • リモートソースからデータをフェッチする
  • リモートソースからデータを受信する

これは一般的に pull 型と push 型のデータ収集と呼ばれ、詳細は Receiver の概要 で読むことができます。

Processor が解決するビジネスユースケースは以下の通りです

  • データ、フィールド、または値の追加や削除
  • データを観測し、意思決定を行う
  • バッファリング、キューイング、並び替え

留意すべき点は、Processor を流れるデータタイプは、下流のコンポーネントに同じデータタイプを転送する必要があるということです。詳細は Processor の概要 をお読みください。

Exporter が解決するビジネスユースケースは以下の通りです

  • ツール、サービス、またはストレージにデータを送信する

OpenTelemetry Collector は「バックエンド」、つまりオールインワンのオブザーバビリティスイートになることを望んでおらず、むしろ OpenTelemetry を創設した原則を維持しています。つまり、すべての人のためのベンダーに依存しないオブザーバビリティです。詳細を再確認するには、Exporter の概要 をお読みください。

これはワークショップで見逃されたコンポーネントタイプです。比較的新しい Collector への追加であるためです。Connector を考える最良の方法は、異なるテレメトリタイプとパイプライン間で使用できる Processor のようなものです。つまり、Connector はログとしてデータを受け入れ、メトリクスを出力したり、あるパイプラインからメトリクスを受け入れ、観測したデータに関するメトリクスを提供したりできます。

Connector が解決するビジネスケースは以下の通りです

  • 異なるテレメトリタイプ間の変換
    • ログからメトリクス
    • トレースからメトリクス
    • メトリクスからログ
  • 受信データを観測し、独自のデータを生成する
    • メトリクスを受け入れ、データの分析メトリクスを生成する。

Processor の概要Ninja セクションに簡単な概要がありました。新しい Connector コンポーネントの更新についてはプロジェクトを確認してください。

コンポーネントの概要から、Jenkins 用のプルベースのレシーバーを開発することが明確です。

Last Modified 2026/01/23

OpenTelemetry Collector 開発

メトリクスの設計

レシーバーでキャプチャしたメトリクスを定義およびエクスポートするために、mdatagen を使用します。これは、YAML で定義されたメトリクスをコードに変換する Collector 用に開発されたツールです。

---
# Type defines the name to reference the component
# in the configuration file
type: jenkins

# Status defines the component type and the stability level
status:
  class: receiver
  stability:
    development: [metrics]

# Attributes are the expected fields reported
# with the exported values.
attributes:
  job.name:
    description: The name of the associated Jenkins job
    type: string
  job.status:
    description: Shows if the job had passed, or failed
    type: string
    enum:
    - failed
    - success
    - unknown

# Metrics defines all the pontentially exported values from this receiver.
metrics:
  jenkins.jobs.count:
    enabled: true
    description: Provides a count of the total number of configured jobs
    unit: "{Count}"
    gauge:
      value_type: int
  jenkins.job.duration:
    enabled: true
    description: Show the duration of the job
    unit: "s"
    gauge:
      value_type: int
    attributes:
    - job.name
    - job.status
  jenkins.job.commit_delta:
    enabled: true
    description: The calculation difference of the time job was finished minus commit timestamp
    unit: "s"
    gauge:
      value_type: int
    attributes:
    - job.name
    - job.status
// To generate the additional code needed to capture metrics,
// the following command to be run from the shell:
//  go generate -x ./...

//go:generate go run github.com/open-telemetry/opentelemetry-collector-contrib/cmd/mdatagen@v0.80.0 metadata.yaml
package jenkinscireceiver

// There is no code defined within this file.

次のセクションに進む前に、これらのファイルをプロジェクトフォルダー内に作成してください。

Factory の構築

Factory は、オブジェクト(この場合は jenkinscireceiver)を提供された設定で動的に作成できるようにするソフトウェアデザインパターンです。より現実世界の例を使うと、電話ショップに行き、自分の説明と正確に一致する電話を求め、それを提供してもらうようなものです。

go generate -x ./... コマンドを実行すると、定義されたメトリクスをエクスポートするために必要なすべてのコードを含む新しいフォルダー jenkinscireceiver/internal/metadata が作成されます。必要なコードは以下の通りです

package jenkinscireceiver

import (
    "errors"

    "go.opentelemetry.io/collector/component"
    "go.opentelemetry.io/collector/config/confighttp"
    "go.opentelemetry.io/collector/receiver"
    "go.opentelemetry.io/collector/receiver/scraperhelper"

    "splunk.conf/workshop/example/jenkinscireceiver/internal/metadata"
)

func NewFactory() receiver.Factory {
    return receiver.NewFactory(
        metadata.Type,
        newDefaultConfig,
        receiver.WithMetrics(newMetricsReceiver, metadata.MetricsStability),
    )
}

func newMetricsReceiver(_ context.Context, set receiver.CreateSettings, cfg component.Config, consumer consumer.Metrics) (receiver.Metrics, error) {
    // Convert the configuration into the expected type
    conf, ok := cfg.(*Config)
    if !ok {
        return nil, errors.New("can not convert config")
    }
    sc, err := newScraper(conf, set)
    if err != nil {
        return nil, err
    }
    return scraperhelper.NewScraperControllerReceiver(
        &conf.ScraperControllerSettings,
        set,
        consumer,
        scraperhelper.AddScraper(sc),
    )
}
package jenkinscireceiver

import (
    "go.opentelemetry.io/collector/config/confighttp"
    "go.opentelemetry.io/collector/receiver/scraperhelper"

    "splunk.conf/workshop/example/jenkinscireceiver/internal/metadata"
)

type Config struct {
    // HTTPClientSettings contains all the values
    // that are commonly shared across all HTTP interactions
    // performed by the collector.
    confighttp.HTTPClientSettings `mapstructure:",squash"`
    // ScraperControllerSettings will allow us to schedule
    // how often to check for updates to builds.
    scraperhelper.ScraperControllerSettings `mapstructure:",squash"`
    // MetricsBuilderConfig contains all the metrics
    // that can be configured.
    metadata.MetricsBuilderConfig `mapstructure:",squash"`
}

func newDefaultConfig() component.Config {
    return &Config{
        ScraperControllerSettings: scraperhelper.NewDefaultScraperControllerSettings(metadata.Type),
        HTTPClientSettings:        confighttp.NewDefaultHTTPClientSettings(),
        MetricsBuilderConfig:      metadata.DefaultMetricsBuilderConfig(),
    }
}
package jenkinscireceiver

type scraper struct {}

func newScraper(cfg *Config, set receiver.CreateSettings) (scraperhelper.Scraper, error) {
    // Create a our scraper with our values
    s := scraper{
        // To be filled in later
    }
    return scraperhelper.NewScraper(metadata.Type, s.scrape)
}

func (scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
    // To be filled in
    return pmetrics.NewMetrics(), nil
}
---
dist:
  name: otelcol
  description: "Conf workshop collector"
  output_path: ./dist
  version: v0.0.0-experimental

extensions:
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/basicauthextension v0.80.0
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.80.0

receivers:
  - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.80.0
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.80.0
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.80.0
  - gomod: splunk.conf/workshop/example/jenkinscireceiver v0.0.0
    path: ./jenkinscireceiver

processors:
  - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.80.0

exporters:
  - gomod: go.opentelemetry.io/collector/exporter/loggingexporter v0.80.0
  - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.80.0
  - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.80.0

# This replace is a go directive that allows for redefine
# where to fetch the code to use since the default would be from a remote project.
replaces:
- splunk.conf/workshop/example/jenkinscireceiver => ./jenkinscireceiver
├── build-config.yaml
└── jenkinscireceiver
    ├── go.mod
    ├── config.go
    ├── factory.go
    ├── scraper.go
    └── internal
      └── metadata

これらのファイルを期待される内容でプロジェクトに書き込んだら、go mod tidy を実行します。これにより、すべてのリモート依存関係がフェッチされ、go.mod が更新され、go.sum ファイルが生成されます。

Last Modified 2026/01/23

OpenTelemetry Collector 開発

ビジネスロジックの構築

この時点で、現在何もしないカスタムコンポーネントがあるため、Jenkins からこのデータをキャプチャするために必要なロジックを追加する必要があります。

ここから、実行する必要があるステップは以下の通りです

  1. Jenkins に接続するクライアントを作成する
  2. 設定されたすべてのジョブをキャプチャする
  3. 設定されたジョブの最後のビルドのステータスを報告する
  4. コミットのタイムスタンプとジョブ完了の時間差を計算する

変更は scraper.go に対して行われます。

Jenkins サーバーに接続できるようにするために、“github.com/yosida95/golang-jenkins” パッケージを使用します。このパッケージは、Jenkins サーバーからデータを読み取るために必要な機能を提供します。

次に、“go.opentelemetry.io/collector/receiver/scraperhelper” ライブラリのヘルパー関数を利用して、コンポーネントの起動が完了した後に Jenkins サーバーに接続できるように start 関数を作成します。

package jenkinscireceiver

import (
    "context"

    jenkins "github.com/yosida95/golang-jenkins"
    "go.opentelemetry.io/collector/component"
    "go.opentelemetry.io/collector/pdata/pmetric"
    "go.opentelemetry.io/collector/receiver"
    "go.opentelemetry.io/collector/receiver/scraperhelper"

    "splunk.conf/workshop/example/jenkinscireceiver/internal/metadata"
)

type scraper struct {
    mb     *metadata.MetricsBuilder
    client *jenkins.Jenkins
}

func newScraper(cfg *Config, set receiver.CreateSettings) (scraperhelper.Scraper, error) {
    s := &scraper{
        mb : metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, set),
    }

    return scraperhelper.NewScraper(
        metadata.Type,
        s.scrape,
        scraperhelper.WithStart(func(ctx context.Context, h component.Host) error {
            client, err := cfg.ToClient(h, set.TelemetrySettings)
            if err != nil {
                return err
            }
            // The collector provides a means of injecting authentication
            // on our behalf, so this will ignore the libraries approach
            // and use the configured http client with authentication.
            s.client = jenkins.NewJenkins(nil, cfg.Endpoint)
            s.client.SetHTTPClient(client)
            return nil
        }),
    )
}

func (s scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
    // To be filled in
    return pmetric.NewMetrics(), nil
}

これで Jenkins レシーバーを初期化するために必要なすべてのセットアップコードが完了しました。

ここからは、入力を待っていた scrape メソッドに焦点を当てます。このメソッドは、設定で構成された間隔(デフォルトでは毎分)で実行されます。

設定されたジョブの数をキャプチャしたい理由は、Jenkins サーバーの成長を確認し、オンボードしたプロジェクトの数を測定できるようにするためです。これを行うために、Jenkins クライアントを呼び出してすべてのジョブをリストし、エラーが報告された場合はメトリクスなしでそれを返し、そうでなければメトリクスビルダーからデータを出力します。

func (s scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
    jobs, err := s.client.GetJobs()
    if err != nil {
        return pmetric.Metrics{}, err
    }

    // Recording the timestamp to ensure
    // all captured data points within this scrape have the same value.
    now := pcommon.NewTimestampFromTime(time.Now())

    // Casting to an int64 to match the expected type
    s.mb.RecordJenkinsJobsCountDataPoint(now, int64(len(jobs)))

    // To be filled in

    return s.mb.Emit(), nil
}

前のステップでは、すべてのジョブをキャプチャし、ジョブの数を報告することができました。このステップでは、各ジョブを調べ、報告された値を使用してメトリクスをキャプチャします。

func (s scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
    jobs, err := s.client.GetJobs()
    if err != nil {
        return pmetric.Metrics{}, err
    }

    // Recording the timestamp to ensure
    // all captured data points within this scrape have the same value.
    now := pcommon.NewTimestampFromTime(time.Now())

    // Casting to an int64 to match the expected type
    s.mb.RecordJenkinsJobsCountDataPoint(now, int64(len(jobs)))

    for _, job := range jobs {
        // Ensure we have valid results to start off with
        var (
            build  = job.LastCompletedBuild
            status = metadata.AttributeJobStatusUnknown
        )

        // This will check the result of the job, however,
        // since the only defined attributes are
        // `success`, `failure`, and `unknown`.
        // it is assume that anything did not finish
        // with a success or failure to be an unknown status.

        switch build.Result {
        case "aborted", "not_built", "unstable":
            status = metadata.AttributeJobStatusUnknown
        case "success":
            status = metadata.AttributeJobStatusSuccess
        case "failure":
            status = metadata.AttributeJobStatusFailed
        }

        s.mb.RecordJenkinsJobDurationDataPoint(
            now,
            int64(job.LastCompletedBuild.Duration),
            job.Name,
            status,
        )
    }

    return s.mb.Emit(), nil
}

最後のステップは、コミットからジョブ完了までにかかった時間を計算し、DORA メトリクスを推測するのに役立てることです。

func (s scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
    jobs, err := s.client.GetJobs()
    if err != nil {
        return pmetric.Metrics{}, err
    }

    // Recording the timestamp to ensure
    // all captured data points within this scrape have the same value.
    now := pcommon.NewTimestampFromTime(time.Now())

    // Casting to an int64 to match the expected type
    s.mb.RecordJenkinsJobsCountDataPoint(now, int64(len(jobs)))

    for _, job := range jobs {
        // Ensure we have valid results to start off with
        var (
            build  = job.LastCompletedBuild
            status = metadata.AttributeJobStatusUnknown
        )

        // Previous step here

        // Ensure that the `ChangeSet` has values
        // set so there is a valid value for us to reference
        if len(build.ChangeSet.Items) == 0 {
            continue
        }

        // Making the assumption that the first changeset
        // item is the most recent change.
        change := build.ChangeSet.Items[0]

        // Record the difference from the build time
        // compared against the change timestamp.
        s.mb.RecordJenkinsJobCommitDeltaDataPoint(
            now,
            int64(build.Timestamp-change.Timestamp),
            job.Name,
            status,
        )
    }

    return s.mb.Emit(), nil
}

これらのステップがすべて完了すると、カスタム Jenkins CI レシーバーの構築が完了です!

次のステップ

コンポーネントから欲しい機能がおそらくもっとあるでしょう。例えば

  • ジョブが使用したブランチ名を含めることはできますか?
  • ジョブのプロジェクト名を含めることはできますか?
  • プロジェクトの累積ジョブ期間をどのように計算しますか?
  • 変更が機能することをどのように検証しますか?

この時間を使って、遊んでみたり、壊してみたり、変更したり、ビルドからログをキャプチャしてみたりしてください。

Last Modified 2026/01/23

Advanced OpenTelemetry Collector

75 minutes   Authors Robert Castley, Charity Anderson, Pieter Hagen, & Geoff Higginbottom

このワークショップの目的は、OpenTelemetry Collector の設定ファイルを作成・変更する際の自信を深めることです。最小限の agent.yamlgateway.yaml ファイルから始め、いくつかの高度な実際のシナリオに対応できるよう段階的に構築していきます。

このワークショップの重要なポイントは、テレメトリーデータをサードパーティベンダーのバックエンドに送信するのではなく、ローカルに保存するよう OpenTelemetry Collector を設定する方法を学ぶことです。このアプローチはデバッグやトラブルシューティングを簡素化するだけでなく、本番システムへのデータ送信を避けたいテストや開発環境にも最適です。

このワークショップを最大限に活用するために、以下の知識が必要です

  • OpenTelemetry Collector とその設定ファイル構造の基本的な理解
  • YAML ファイルの編集スキル

このワークショップのすべての内容はローカルで実行できるよう設計されており、実践的でアクセスしやすい学習体験を提供します。それでは、構築を始めましょう!

ワークショップの概要

このワークショップでは、以下のトピックを取り上げます

  • Agent と Gateway をローカルでセットアップ: メトリクス、トレース、ログが Agent 経由で Gateway に送られることをテストします。
  • Agent の耐障害性を強化: フォールトトレランスのための基本設定を行います。
  • Processor の設定:
    • 特定のスパン(例:ヘルスチェック)をドロップしてノイズをフィルタリングします。
    • 不要なタグを削除し、機密データを処理します。
    • エクスポート前にパイプラインで OTTL(OpenTelemetry Transformation Language)を使用してデータを変換します。
  • Connector の設定:
    • 受信した値に基づいて、データを異なるエンドポイントにルーティングします。

このワークショップを終了すると、さまざまな実際のユースケースに対応する OpenTelemetry Collector の設定に精通しているでしょう。

Last Modified 2026/01/28

Advanced OpenTelemetry Collectorのサブセクション

前提条件

5 minutes  

前提条件

  • vivimnano、またはお好みのテキストエディタを使用して YAML ファイルを編集するスキル
  • サポートされている環境
    • 提供される Splunk Workshop インスタンス(推奨)。ssh アクセス用にポート 2222 への外部アクセスが必要です。
    • Apple Mac(Apple Silicon)。jq のインストールが必要です - https://jqlang.org/download/
Exercise

ディレクトリの作成: 環境内で新しいディレクトリを作成し、そのディレクトリに移動します

mkdir advanced-otel-workshop && \
cd advanced-otel-workshop

このワークショップの残りの部分では、このディレクトリを [WORKSHOP] と呼びます。

既存の OpenTelemetry Collector を削除してください

Splunk IM ワークショップを完了している場合は、続行する前に Kubernetes で実行中の Collector を削除してください。以下のコマンドを実行して削除できます

helm delete splunk-otel-collector

その場合、EC2 インスタンスでこのワークショップと干渉する可能性のあるサービスが実行されている場合があるため、以下のコマンドを実行してそれらが存在する場合は停止してください

kubectl delete ~/workshop/apm/deployment.yaml

ワークショップバイナリのダウンロード: [WORKSHOP] ディレクトリに移動し、OpenTelemetry Collector、Load Generator バイナリ、およびセットアップスクリプトをダウンロードします

curl -L https://github.com/signalfx/splunk-otel-collector/releases/download/v0.136.0/otelcol_linux_amd64 -o otelcol && \
curl -L https://github.com/splunk/observability-workshop/raw/refs/heads/main/workshop/ninja/advanced-otel/loadgen/build/loadgen-linux-amd64 -o loadgen && \
curl -L https://github.com/splunk/observability-workshop/raw/refs/heads/main/workshop/ninja/advanced-otel/setup-workshop.sh -o setup-workshop.sh && \
chmod +x setup-workshop.sh
curl -L https://github.com/signalfx/splunk-otel-collector/releases/download/v0.136.0/otelcol_darwin_arm64 -o otelcol && \
curl -L https://github.com/splunk/observability-workshop/raw/refs/heads/main/workshop/ninja/advanced-otel/loadgen/build/loadgen-darwin-arm64 -o loadgen && \
curl -L https://github.com/splunk/observability-workshop/raw/refs/heads/main/workshop/ninja/advanced-otel/setup-workshop.sh -o setup-workshop.sh && \
chmod +x setup-workshop.sh

setup-workshop.sh スクリプトを実行します。このスクリプトは正しい権限を設定し、AgentGateway の初期設定も作成します

./setup-workshop.sh
███████╗██████╗ ██╗     ██╗   ██╗███╗   ██╗██╗  ██╗    ██╗
██╔════╝██╔══██╗██║     ██║   ██║████╗  ██║██║ ██╔╝    ╚██╗
███████╗██████╔╝██║     ██║   ██║██╔██╗ ██║█████╔╝      ╚██╗
╚════██║██╔═══╝ ██║     ██║   ██║██║╚██╗██║██╔═██╗      ██╔╝
███████║██║     ███████╗╚██████╔╝██║ ╚████║██║  ██╗    ██╔╝
╚══════╝╚═╝     ╚══════╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝    ╚═╝

Welcome to the Splunk Advanced OpenTelemetry Workshop!
======================================================

macOS detected. Removing quarantine attributes...
otelcol version v0.126.0
Usage: loadgen [OPTIONS]
Options:
  -base       Send base traces (enabled by default)
  -health     Send health traces
  -security   Send security traces
  -logs       Enable logging of random quotes to quotes.log
  -json       Output logs in JSON format (only applicable with -logs)
  -count      Number of traces or logs to send (default: infinite)
  -h, --help  Display this help message

Example:
  loadgen -health -security -count 10   Send 10 health and security traces
  loadgen -logs -json -count 5          Write 5 random quotes in JSON format to quotes.log
Creating workshop directories...
✓ Created subdirectories:
  ├── 1-agent-gateway
  ├── 2-building-resilience
  ├── 3-dropping-spans
  ├── 4-sensitive-data
  ├── 5-transform-data
  ├── 6-routing-data
  └── 7-sum-count

Creating configuration files for 1-agent-gateway...
Creating OpenTelemetry Collector agent configuration file: 1-agent-gateway/agent.yaml
✓ Configuration file created successfully: 1-agent-gateway/agent.yaml
✓ File size:     4355 bytes

Creating OpenTelemetry Collector gateway configuration file: 1-agent-gateway/gateway.yaml
✓ Configuration file created successfully: 1-agent-gateway/gateway.yaml
✓ File size:     3376 bytes

✓ Completed configuration files for 1-agent-gateway

Creating configuration files for 2-building-resilience...
Creating OpenTelemetry Collector agent configuration file: 2-building-resilience/agent.yaml
✓ Configuration file created successfully: 2-building-resilience/agent.yaml
✓ File size:     4355 bytes

Creating OpenTelemetry Collector gateway configuration file: 2-building-resilience/gateway.yaml
✓ Configuration file created successfully: 2-building-resilience/gateway.yaml
✓ File size:     3376 bytes

✓ Completed configuration files for 2-building-resilience

Workshop environment setup complete!
Configuration files created in the following directories:
  1-agent-gateway/
    ├── agent.yaml
    └── gateway.yaml
  2-building-resilience/
    ├── agent.yaml
    └── gateway.yaml
[WORKSHOP]
├── 1-agent-gateway
├── 2-building-resilience
├── 3-dropping-spans
├── 4-sensitive-data
├── 5-transform-data
├── 6-routing-data
├── 7-sum-count
├── loadgen
├── otelcol
└── setup-workshop.sh
Last Modified 2026/01/23

1. Agent 設定の確認

15 minutes  

ようこそ!このセクションでは、AgentGateway の両方を含む完全に機能する OpenTelemetry セットアップから始めます。

まず、設定ファイルを簡単に確認して、全体的な構造に慣れ、テレメトリーパイプラインを制御する重要なセクションを確認します。

Tip

ワークショップを通じて、複数のターミナルウィンドウを使用します。整理しやすくするために、各ターミナルに固有の名前または色を付けてください。これにより、演習中にターミナルを簡単に識別して切り替えることができます。

これらのターミナルを AgentGatewayLoadgenTest と呼びます。

Exercise
  1. 最初のターミナルウィンドウを作成し、Agent と名前を付けます。最初の演習用ディレクトリ [WORKSHOP]/1-agent-gateway に移動し、必要なファイルが生成されていることを確認します

    cd 1-agent-gateway
    ls -l
  2. ディレクトリに以下のファイルが表示されるはずです。表示されない場合は、前提条件 セクションで説明されている setup-workshop.sh スクリプトを再実行してください

    .
    ├── agent.yaml
    └── gateway.yaml

Agent 設定の理解

このワークショップで使用する agent.yaml ファイルの主要なコンポーネントを確認しましょう。メトリクス、トレース、ログをサポートするために重要な追加が行われています。

Receiver

receivers セクションは、Agent がテレメトリーデータを取り込む方法を定義します。このセットアップでは、3種類の Receiver が設定されています

  • Host Metrics Receiver

    hostmetrics:                         # Host Metrics Receiver
      collection_interval: 3600s         # Collection Interval (1hr)
      scrapers:
        cpu:                             # CPU Scraper

    ローカルシステムから1時間ごとに CPU 使用率を収集します。これを使用してサンプルメトリクスデータを生成します。

  • OTLP Receiver(HTTP プロトコル)

    otlp:                                # OTLP Receiver
      protocols:
        http:                            # Configure HTTP protocol
          endpoint: "0.0.0.0:4318"       # Endpoint to bind to

    Agent がポート 4318 で HTTP 経由でメトリクス、トレース、ログを受信できるようにします。これは、今後の演習で Collector にデータを送信するために使用されます。

  • FileLog Receiver

    filelog/quotes:                      # Receiver Type/Name
      include: ./quotes.log              # The file to read log data from
      include_file_path: true            # Include file path in the log data
      include_file_name: false           # Exclude file name from the log data
      resource:                          # Add custom resource attributes
        com.splunk.source: ./quotes.log  # Source of the log data
        com.splunk.sourcetype: quotes    # Source type of the log data

    Agent がローカルログファイル(quotes.log)を tail し、sourcesourceType などのメタデータで強化された構造化ログイベントに変換できるようにします。

Exporter

  • Debug Exporter

      debug:                               # Exporter Type
        verbosity: detailed                # Enabled detailed debug output
  • OTLPHTTP Exporter

      otlphttp:                            # Exporter Type
        endpoint: "http://localhost:5318"  # Gateway OTLP endpoint

    debug Exporter はワークショップ中の可視性とデバッグのためにデータをコンソールに送信し、otlphttp Exporter はすべてのテレメトリーをローカルの Gateway インスタンスに転送します。

    このデュアルエクスポート戦略により、生データをローカルで確認しながら、さらなる処理とエクスポートのためにダウンストリームに送信することができます。

Last Modified 2026/01/23

1. Agent Configurationのサブセクション

1.1 Gateway 設定の確認

OpenTelemetry Gateway は、テレメトリーデータの受信、処理、エクスポートのための中央ハブとして機能します。テレメトリーソース(アプリケーションやサービスなど)と Splunk Observability Cloud のようなオブザーバビリティバックエンドの間に位置します。

テレメトリートラフィックを集中化することで、Gateway はデータのフィルタリング、エンリッチメント、変換、および1つ以上の宛先へのルーティングなどの高度な機能を実現します。個々のサービスからテレメトリー処理をオフロードすることで負担を軽減し、分散システム全体で一貫した標準化されたデータを確保します。

これにより、オブザーバビリティパイプラインの管理、スケーリング、分析が容易になります。特に複雑なマルチサービス環境では効果的です。

Exercise

2つ目のターミナルウィンドウを開くか作成し、Gateway と名前を付けます。最初の演習ディレクトリ [WORKSHOP]/1-agent-gateway に移動し、gateway.yaml ファイルの内容を確認します。

このファイルは、Gateway モードでデプロイされた OpenTelemetry Collector のコア構造を示しています。

Gateway 設定の理解

このワークショップで Gateway モードの OpenTelemetry Collector がどのように設定されているかを定義する gateway.yaml ファイルを確認しましょう。この Gateway は、Agent からテレメトリーを受信し、処理してから検査または転送のためにエクスポートする役割を担います。

  • OTLP Receiver(カスタムポート)

    receivers:
      otlp:
        protocols:
          http:
            endpoint: "0.0.0.0:5318"

    ポート 5318Agent 設定の otlphttp Exporter と一致しており、Agent が送信するすべてのテレメトリーデータが Gateway で受け入れられることを保証します。

メモ

このポートの分離により、競合を回避し、Agent と Gateway の役割間の責任を明確に保ちます。

  • File Exporter

    Gateway は3つの File Exporter を使用して、テレメトリーデータをローカルファイルに出力します。これらの Exporter は以下のように定義されています

    exporters:                        # List of exporters
      debug:                          # Debug exporter
        verbosity: detailed           # Enable detailed debug output
      file/traces:                    # Exporter Type/Name
        path: "./gateway-traces.out"  # Path for OTLP JSON output for traces
        append: false                 # Overwrite the file each time
      file/metrics:                   # Exporter Type/Name
        path: "./gateway-metrics.out" # Path for OTLP JSON output for metrics
        append: false                 # Overwrite the file each time
      file/logs:                      # Exporter Type/Name
        path: "./gateway-logs.out"    # Path for OTLP JSON output for logs
        append: false                 # Overwrite the file each time

    各 Exporter は、特定のシグナルタイプを対応するファイルに書き込みます。

    これらのファイルは Gateway が起動すると作成され、Agent がデータを送信すると実際のテレメトリーが書き込まれます。これらのファイルをリアルタイムで監視して、パイプラインを通過するテレメトリーの流れを観察できます。

Last Modified 2026/01/23

1.2 設定の検証とテスト

次に、GatewayAgent を起動します。Agent は起動時に自動的に Host Metrics を送信するよう設定されています。これにより、データが Agent から Gateway に正しくルーティングされることを確認します。

Exercise

Gateway: Gateway ターミナル ウィンドウで、以下のコマンドを実行して Gateway を起動します

../otelcol --config=gateway.yaml

すべてが正しく設定されている場合、Collector が起動し、出力に Everything is ready. Begin running and processing data. と表示されます。以下のような出力になります

2025-06-09T09:22:11.944+0100    info    service@v0.126.0/service.go:289 Everything is ready. Begin running and processing data. {"resource": {}}

Gateway が実行されると、ポート 5318 で受信データをリッスンし、受信したデータを以下のファイルにエクスポートします

  • gateway-traces.out
  • gateway-metrics.out
  • gateway-logs.out

Agent の起動: Agent ターミナル ウィンドウで、Agent 設定を使用して Agent を起動します

../otelcol --config=agent.yaml

CPU メトリクスの確認:

  1. Agent が起動すると、すぐに CPU メトリクスの送信を開始することを確認します。
  2. AgentGateway の両方がデバッグ出力にこのアクティビティを表示します。出力は以下のスニペットのようになります
<snip>
NumberDataPoints #31
Data point attributes:
     -> cpu: Str(cpu3)
     -> state: Str(wait)
StartTimestamp: 2025-07-07 16:49:42 +0000 UTC
Timestamp: 2025-07-09 09:36:21.190226459 +0000 UTC
Value: 77.380000
        {"resource": {}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "metrics"}

この段階で、Agent は1時間ごとまたは再起動ごとに CPU メトリクスを収集し、Gateway に送信し続けます。Gateway はこれらのメトリクスを処理し、gateway-metrics.out という名前のファイルにエクスポートします。このファイルは、パイプラインサービスの一部としてエクスポートされたメトリクスを保存します。

Gateway にデータが到着したことの確認: CPU メトリクス(特に cpu0)が Gateway に正常に到達したことを確認するために、jq コマンドを使用して gateway-metrics.out ファイルを検査します。

以下のコマンドは、system.cpu.time メトリクスをフィルタリングして抽出し、cpu0 に焦点を当てます。メトリクスの状態(例:usersystemidleinterrupt)と対応する値を表示します。

3つ目のターミナルウィンドウを開くか作成し、Tests と名前を付けます。Tests ターミナル で以下のコマンドを実行して system.cpu.time メトリクスを確認します

jq '.resourceMetrics[].scopeMetrics[].metrics[] | select(.name == "system.cpu.time") | .sum.dataPoints[] | select(.attributes[0].value.stringValue == "cpu0") | {cpu: .attributes[0].value.stringValue, state: .attributes[1].value.stringValue, value: .asDouble}' gateway-metrics.out
{
  "cpu": "cpu0",
  "state": "user",
  "value": 123407.02
}
{
  "cpu": "cpu0",
  "state": "system",
  "value": 64866.6
}
{
  "cpu": "cpu0",
  "state": "idle",
  "value": 216427.87
}
{
  "cpu": "cpu0",
  "state": "interrupt",
  "value": 0
}
重要

AgentGateway のプロセスを、それぞれのターミナルで Ctrl-C を押して停止してください。

Last Modified 2026/01/23

2. 耐障害性の構築

10 minutes  

OpenTelemetry Collector の FileStorage Extension は、より耐障害性の高いテレメトリーパイプラインを構築するための重要なコンポーネントです。これにより、Collector は処理中のデータを確実にチェックポイントし、リトライを効率的に管理し、貴重なテレメトリーを失うことなく一時的な障害を適切に処理できます。

FileStorage を有効にすると、Collector は中間状態をディスクに永続化できるため、ネットワークの中断、バックエンドの停止、または Collector の再起動時にもトレース、メトリクス、ログが失われないことが保証されます。つまり、ネットワーク接続が切断されたり、バックエンドが一時的に利用できなくなったりしても、Collector はテレメトリーの受信とバッファリングを継続し、接続が復旧すると配信をシームレスに再開します。

FileStorage Extension をパイプラインに統合することで、オブザーバビリティスタックの耐久性を強化し、接続が不安定な環境でも高品質なテレメトリー取り込みを維持できます。

メモ

このソリューションは、接続ダウンタイムが短い場合(最大15分)のメトリクスに対して機能します。ダウンタイムがこれを超えると、Splunk Observability Cloud はデータポイントの順序が乱れないようにデータをドロップする可能性があります。

ログについては、今後の Splunk OpenTelemetry Collector リリースで完全なエンタープライズ対応ソリューションを実装する計画があります。

Last Modified 2026/01/09

2. Building Resilienceのサブセクション

2.1 File Storage の設定

この演習では、agent.yaml ファイルの extensions: セクションを更新します。このセクションは OpenTelemetry 設定 YAML の一部であり、OpenTelemetry Collector の動作を拡張または変更するオプションのコンポーネントを定義します。

これらのコンポーネントはテレメトリーデータを直接処理しませんが、Collector の機能を向上させる貴重な機能とサービスを提供します。

Exercise
重要

すべての ターミナルウィンドウを 2-building-resilience ディレクトリに移動し、clear コマンドを実行してください。

ディレクトリ構造は以下のようになります

.
├── agent.yaml
└── gateway.yaml

agent.yaml の更新: Agent ターミナル ウィンドウで、既存の health_check Extension の下に file_storage Extension を追加します

  file_storage/checkpoint:             # Extension Type/Name
    directory: "./checkpoint-dir"      # Define directory
    create_directory: true             # Create directory
    timeout: 1s                        # Timeout for file operations
    compaction:                        # Compaction settings
      on_start: true                   # Start compaction at Collector startup
      # Define compaction directory
      directory: "./checkpoint-dir/tmp"
      max_transaction_size: 65536      # Max. size limit before compaction occurs

Exporter への file_storage の追加: otlphttp Exporter を変更して、リトライとキューイングメカニズムを設定し、障害が発生した場合にデータが保持され再送信されるようにします。endpoint: "http://localhost:5318" の下に以下を追加し、インデントが endpoint と一致していることを確認してください

    retry_on_failure:
      enabled: true                    # Enable retry on failure
    sending_queue:                     #
      enabled: true                    # Enable sending queue
      num_consumers: 10                # No. of consumers
      queue_size: 10000                # Max. queue size
      storage: file_storage/checkpoint # File storage extension

services セクションの更新: 既存の extensions: セクションに file_storage/checkpoint Extension を追加します。設定は以下のようになります

service:
  extensions:
  - health_check
  - file_storage/checkpoint            # Enabled extensions for this collector

metrics パイプラインの更新: この演習では、デバッグとログのノイズを減らすために、Metric パイプラインから hostmetrics Receiver をコメントアウトします。設定は以下のようになります

    metrics:
      receivers:
      # - hostmetrics                    # Hostmetric reciever (cpu only)
      - otlp

otelbin.io を使用して Agent 設定を検証してください。参考までに、パイプラインの metrics: セクションは以下のようになります

%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
      REC1(&nbsp;&nbsp;otlp&nbsp;&nbsp;<br>fa:fa-download):::receiver
      PRO1(memory_limiter<br>fa:fa-microchip):::processor
      PRO2(resourcedetection<br>fa:fa-microchip):::processor
      PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
      EXP1(&ensp;debug&ensp;<br>fa:fa-upload):::exporter
      EXP2(otlphttp<br>fa:fa-upload):::exporter
      EXP3(&ensp;file&ensp;<br>fa:fa-upload):::exporter
    %% Links
    subID1:::sub-metrics
    subgraph " "
      subgraph subID1[**Metrics**]
      direction LR
      REC1 --> PRO1
      PRO1 --> PRO2
      PRO2 --> PRO3
      PRO3 --> EXP1
      PRO3 --> EXP3
      PRO3 --> EXP2
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-metrics stroke:#38bdf8,stroke-width:1px, color:#38bdf8,stroke-dasharray: 3 3;
Last Modified 2026/01/23

2.2 耐障害性テスト用の環境セットアップ

次に、File Storage 設定をテストする準備として環境を設定します。

Exercise

Gateway の起動: Gateway ターミナル ウィンドウで以下を実行します

../otelcol --config=gateway.yaml

Agent の起動: Agent ターミナル ウィンドウで以下を実行します

../otelcol --config=agent.yaml

5つのテストスパンを送信: Loadgen ターミナル ウィンドウで以下を実行します

../loadgen -count 5

AgentGateway の両方がデバッグログを表示し、Gateway./gateway-traces.out ファイルを作成するはずです。

すべてが正常に機能している場合、システムの耐障害性のテストに進むことができます。

Last Modified 2026/01/23

2.3 障害のシミュレーション

Agent の耐障害性を評価するために、一時的な Gateway の停止をシミュレートし、Agent がそれをどのように処理するかを観察します

Exercise

ネットワーク障害のシミュレーション: Gateway ターミナルCtrl-C を使用して Gateway を停止し、Gateway のコンソールが停止したことを示すまで待ちます。Agent は引き続き実行されますが、Gateway にデータを送信できません。Gateway ターミナル の出力は以下のようになります

2025-07-09T10:22:37.941Z        info    service@v0.126.0/service.go:345 Shutdown complete.      {"resource": {}}

トレースの送信: Loadgen ターミナル ウィンドウで、loadgen を使用してさらに5つのトレースを送信します。

../loadgen -count 5

Agent のリトライメカニズムが有効になり、データを再送信しようと継続的に試みていることに注目してください。Agent のコンソール出力には、以下のようなメッセージが繰り返し表示されます

2025-01-28T14:22:47.020+0100  info  internal/retry_sender.go:126  Exporting failed. Will retry the request after interval.  {"kind": "exporter", "data_type": "traces", "name": "otlphttp", "error": "failed to make an HTTP request: Post \"http://localhost:5318/v1/traces\": dial tcp 127.0.0.1:5318: connect: connection refused", "interval": "9.471474933s"}

Agent の停止: Agent ターミナル ウィンドウで、Ctrl-C を使用して Agent を停止します。Agent のコンソールが停止を確認するまで待ちます

2025-07-09T10:25:59.344Z        info    service@v0.126.0/service.go:345 Shutdown complete.      {"resource": {}}
重要

Agent を停止すると、リトライ用にメモリに保持されているメトリクス、トレース、ログは失われます。ただし、FileStorage Extension を設定しているため、ターゲットエンドポイントでまだ受け入れられていないすべてのテレメトリーはディスクに安全にチェックポイントされています。

Agent の停止は、Agent が再起動されたときにシステムがどのように復旧するかを明確に示すための重要なステップです。

Last Modified 2026/01/23

2.4 復旧

この演習では、Gateway Collector を再起動することで、OpenTelemetry Collector がネットワーク障害からどのように復旧するかをテストします。Gateway が再び利用可能になると、Agent は最後にチェックポイントされた状態からデータの送信を再開し、データ損失がないことを保証します。

Exercise

Gateway の再起動: Gateway ターミナル ウィンドウで以下を実行します

../otelcol --config=gateway.yaml

Agent の再起動: Agent ターミナル ウィンドウで以下を実行します

../otelcol --config=agent.yaml

Agent が起動して実行されると、File_Storage Extension がチェックポイントフォルダー内のバッファされたデータを検出します。最後のチェックポイントフォルダーから保存されたスパンをデキューし始め、データが失われないことを保証します。

Agent デバッグ出力の確認: Agent のデバッグ出力は変化せず、以下の行を表示し続け、新しいデータがエクスポートされていないことを示していることに注意してください

2025-07-11T08:31:58.176Z        info    service@v0.126.0/service.go:289 Everything is ready. Begin running and processing data.   {"resource": {}}

Gateway デバッグ出力の確認 Gateway のデバッグ画面から、以前見逃されていたトレースを追加のアクションなしで受信し始めていることが確認できるはずです。例

Attributes:
   -> user.name: Str(Luke Skywalker)
   -> user.phone_number: Str(+1555-867-5309)
   -> user.email: Str(george@deathstar.email)
   -> user.password: Str(LOTR>StarWars1-2-3)
   -> user.visa: Str(4111 1111 1111 1111)
   -> user.amex: Str(3782 822463 10005)
   -> user.mastercard: Str(5555 5555 5555 4444)
   -> payment.amount: Double(75.75)
      {"resource": {}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}

gateway-traces.out ファイルの確認: jq を使用して、再作成された gateway-traces.out 内のトレース数をカウントします。Gateway がダウンしていたときに送信した数と一致するはずです。

jq '.resourceSpans | length | "\(.) resourceSpans found"' gateway-traces.out
"5 resourceSpans found"
重要

AgentGateway のプロセスを、それぞれのターミナルで Ctrl-C を押して停止してください。

まとめ

この演習では、file_storage Extension の設定、otlp Exporter のリトライメカニズムの有効化、および一時的なデータ保存用のファイルベースのキューの使用により、OpenTelemetry Collector の耐障害性を強化する方法を示しました。

ファイルベースのチェックポイントとキューの永続化を実装することで、テレメトリーパイプラインが一時的な中断から適切に復旧できることを保証し、本番環境でより堅牢で信頼性の高いものにします。

Last Modified 2026/01/23

3. Spanのドロップ

5 minutes  

このセクションでは、Filter Processor を使用して、特定の条件に基づいてSpanを選択的にドロップする方法を説明します。

具体的には、Span名に基づいてトレースをドロップします。これは、ヘルスチェックや内部通信トレースなどの不要なSpanをフィルタリングするためによく使用されます。今回は、ヘルスチェックリクエストに関連付けられることが多く、通常は非常に「ノイジー」な "/_healthz" を含むSpanをフィルタリングします。

Exercise
重要

すべてのターミナルウィンドウを 3-dropping-spans ディレクトリに移動し、clear コマンドを実行してください。

2-building-resilience ディレクトリから *.yaml3-dropping-spans にコピーします。更新後のディレクトリ構造は次のようになります

.
├── agent.yaml
└── gateway.yaml

次に、filter processor と対応するパイプラインを設定します。

Last Modified 2026/01/23

3. Spanのドロップのサブセクション

3.1 設定

Exercise

Gateway terminal ウィンドウに切り替えて、gateway.yaml ファイルを開きます。以下の設定で processors セクションを更新します

  1. filter プロセッサを追加する /_healthz という名前のSpanを除外するようにGatewayを設定します。error_mode: ignore ディレクティブは、フィルタリング中に発生したエラーを無視し、パイプラインがスムーズに動作し続けることを保証します。traces セクションはフィルタリングルールを定義し、/_healthz という名前のSpanを除外対象として指定します。

      filter/health:                       # Defines a filter processor
        error_mode: ignore                 # Ignore errors
        traces:                            # Filtering rules for traces
          span:                            # Exclude spans named "/_healthz"
           - 'name == "/_healthz"'
  2. traces パイプラインに filter プロセッサを追加する traces パイプラインに filter/health プロセッサを追加します。最適なパフォーマンスを得るために、フィルターはできるだけ早い段階に配置します。memory_limiter の直後、batch プロセッサの前に配置してください。設定は次のようになります

      traces:
        receivers:
          - otlp
        processors:
          - memory_limiter
          - filter/health             # Filters data based on rules
          - resource/add_mode
          - batch
        exporters:
          - debug
          - file/traces

この設定により、ヘルスチェック関連のSpan(/_healthz)がパイプラインの早い段階でフィルタリングされ、テレメトリーデータの不要なノイズが削減されます。

otelbin.io を使用してAgent設定を検証します。参考として、パイプラインの traces: セクションは次のようになります

%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
      REC1(&nbsp;&nbsp;otlp&nbsp;&nbsp;<br>fa:fa-download):::receiver
      PRO1(memory_limiter<br>fa:fa-microchip):::processor
      PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
      PRO4(filter<br>fa:fa-microchip<br>health):::processor
      PRO5(batch<br>fa:fa-microchip):::processor
      EXP1(&ensp;debug&ensp;<br>fa:fa-upload):::exporter
      EXP2(&ensp;&ensp;file&ensp;&ensp;<br>fa:fa-upload<br>traces):::exporter
    %% Links
    subID1:::sub-traces
    subgraph " "
      subgraph subID1[**Traces**]
      direction LR
      REC1 --> PRO1
      PRO1 --> PRO4
      PRO4 --> PRO3
      PRO3 --> PRO5
      PRO5 --> EXP1
      PRO5 --> EXP2
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-traces stroke:#fbbf24,stroke-width:1px, color:#fbbf24,stroke-dasharray: 3 3;
Last Modified 2026/01/23

3.2 Filter Processorのテスト

設定をテストするには、"/_healthz" という名前のSpanを含むトレースデータを生成する必要があります。

Exercise

Gatewayを起動するGateway terminal ウィンドウで Gateway を起動します。

../otelcol --config ./gateway.yaml

Agentを起動するAgent terminal ウィンドウで Agent を起動します。

../otelcol --config ./agent.yaml

Loadgenを起動するLoadgen terminal ウィンドウで、次のコマンドを実行してヘルスチェックSpanを有効にした状態でロードジェネレーターを起動します

../loadgen -health -count 5

Agent terminal のデバッグ出力に _healthz Spanが表示されます

InstrumentationScope healthz 1.0.0
Span #0
   Trace ID       : 0cce8759b5921c8f40b346b2f6e2f4b6
   Parent ID      :
   ID             : bc32bd0e4ddcb174
   Name           : /_healthz
   Kind           : Server
   Start time     : 2025-07-11 08:47:50.938703979 +0000 UTC
   End time       : 2025-07-11 08:47:51.938704091 +0000 UTC
   Status code    : Ok
   Status message : Success

これらは、先ほど設定したFilter Processorによってドロップされるため、Gateway のデバッグ出力には表示されません。

agent.out を確認するTest terminaljq を使用して、Agent が受信したSpanの名前を確認します

jq -c '.resourceSpans[].scopeSpans[].spans[] | "Span \(input_line_number) found with name \(.name)"' ./agent.out
"Span 1 found with name /movie-validator"
"Span 2 found with name /_healthz"
"Span 3 found with name /movie-validator"
"Span 4 found with name /_healthz"
"Span 5 found with name /movie-validator"
"Span 6 found with name /_healthz"
"Span 7 found with name /movie-validator"
"Span 8 found with name /_healthz"
"Span 9 found with name /movie-validator"
"Span 10 found with name /_healthz"

Gateway のデバッグ出力を確認するjq を使用して、Gateway が受信したSpanの名前を確認します

jq -c '.resourceSpans[].scopeSpans[].spans[] | "Span \(input_line_number) found with name \(.name)"' ./gateway-traces.out

gateway-metrics.out ファイルには /_healthz という名前のSpanは含まれません。

"Span 1 found with name /movie-validator"
"Span 2 found with name /movie-validator"
"Span 3 found with name /movie-validator"
"Span 4 found with name /movie-validator"
"Span 5 found with name /movie-validator"
Tip

Filter Processorで最適なパフォーマンスを確保するには、受信データの形式を十分に理解し、設定を厳密にテストしてください。できるだけ具体的なフィルタリング条件を使用して、重要なデータを誤ってドロップするリスクを最小限に抑えてください。

この設定は、さまざまな属性、タグ、またはカスタム条件に基づいてSpanをフィルタリングするように拡張でき、特定のオブザーバビリティ要件に合わせて OpenTelemetry Collector の柔軟性と効率を向上させることができます。

重要

AgentGateway プロセスを、それぞれのターミナルで Ctrl-C を押して停止してください。

Last Modified 2026/01/23

4. 機密データの秘匿化

10 minutes  

このセクションでは、OpenTelemetry Collector を設定して、テレメトリーSpanから特定のタグを削除し、機密データを秘匿化する方法を学びます。これは、クレジットカード番号、個人データ、その他のセキュリティ関連の詳細など、処理またはエクスポートする前に匿名化する必要がある機密情報を保護するために重要です。

OpenTelemetry Collector の主要なプロセッサの設定について説明します

  • Attributes Processor:特定のSpan属性を変更または削除します。
  • Redaction Processor:機密データが保存または送信される前にサニタイズされることを保証します。
Exercise
重要

すべてのターミナルウィンドウを 4-sensitive-data ディレクトリに移動し、clear コマンドを実行してください。

3-dropping-spans ディレクトリから *.yaml4-sensitive-data にコピーします。更新後のディレクトリ構造は次のようになります

.
├── agent.yaml
└── gateway.yaml
Last Modified 2026/01/23

4. 機密データのサブセクション

4.1 設定

このステップでは、agent.yaml を修正して attributesredaction プロセッサを追加します。これらのプロセッサは、Span属性内の機密データがログに記録またはエクスポートされる前に適切に処理されるようにします。

以前、コンソールに表示されたSpan属性の一部に個人情報や機密データが含まれていることに気づいたかもしれません。これから、この情報を効果的にフィルタリングおよび秘匿化するために必要なプロセッサを設定します。

Attributes:
     -> user.name: Str(George Lucas)
     -> user.phone_number: Str(+1555-867-5309)
     -> user.email: Str(george@deathstar.email)
     -> user.account_password: Str(LOTR>StarWars1-2-3)
     -> user.visa: Str(4111 1111 1111 1111)
     -> user.amex: Str(3782 822463 10005)
     -> user.mastercard: Str(5555 5555 5555 4444)
  {"kind": "exporter", "data_type": "traces", "name": "debug"}
Exercise

Agent terminal ウィンドウに切り替えて、エディタで agent.yaml ファイルを開きます。テレメトリーデータのセキュリティとプライバシーを強化するために、2つのプロセッサを追加します。

1. attributes プロセッサを追加するAttributes Processor を使用すると、Span属性(タグ)の値を更新、削除、またはハッシュ化して変更できます。これは、機密情報をエクスポートする前に難読化する場合に特に便利です。

このステップでは

  1. user.phone_number 属性を静的な値("UNKNOWN NUMBER")に更新します。
  2. user.email 属性をハッシュ化して、元のメールアドレスが公開されないようにします。
  3. user.password 属性を削除して、Spanから完全に取り除きます。
  attributes/update:
    actions:                           # Actions
      - key: user.phone_number         # Target key
        action: update                 # Update action
        value: "UNKNOWN NUMBER"        # New value
      - key: user.email                # Target key
        action: hash                   # Hash the email value
      - key: user.password             # Target key
        action: delete                 # Delete the password

2. redaction プロセッサを追加するRedaction Processor は、クレジットカード番号やその他の個人識別情報(PII)などの定義済みパターンに基づいて、Span属性内の機密データを検出して秘匿化します。

このステップでは

  • すべての属性が処理されるように allow_all_keys: true を設定します(false に設定すると、明示的に許可されたキーのみが保持されます)。

  • VisaMasterCard のクレジットカード番号を検出して秘匿化するための正規表現を blocked_values で定義します。

  • summary: debug オプションは、デバッグ目的で秘匿化プロセスに関する詳細情報をログに記録します。

  redaction/redact:
    allow_all_keys: true               # If false, only allowed keys will be retained
    blocked_values:                    # List of regex patterns to block
      - '\b4[0-9]{3}[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}\b'       # Visa
      - '\b5[1-5][0-9]{2}[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}\b'  # MasterCard
    summary: debug                     # Show debug details about redaction

traces パイプラインを更新する:両方のプロセッサを traces パイプラインに統合します。最初は redaction プロセッサをコメントアウトしておいてください(後の演習で有効にします)。設定は次のようになります

    traces:
      receivers:
      - otlp
      processors:
      - memory_limiter
      - attributes/update              # Update, hash, and remove attributes
      #- redaction/redact               # Redact sensitive fields using regex
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - file
      - otlphttp

otelbin.io を使用してAgent設定を検証します。参考として、パイプラインの traces: セクションは次のようになります

%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
      REC1(&nbsp;&nbsp;otlp&nbsp;&nbsp;<br>fa:fa-download):::receiver
      PRML(memory_limiter<br>fa:fa-microchip):::processor
      PRRD(resourcedetection<br>fa:fa-microchip):::processor
      PRRS(resource<br>fa:fa-microchip<br>add_mode):::processor
      PRUP(attributes<br>fa:fa-microchip<br>update):::processor
      EXP1(otlphttp<br>fa:fa-upload):::exporter
      EXP2(&ensp;&ensp;debug&ensp;&ensp;<br>fa:fa-upload):::exporter
      EXP3(file<br>fa:fa-upload):::exporter

    %% Links
    subID1:::sub-traces
    subgraph " "
      subgraph subID1[**Traces**]
      direction LR
      REC1 --> PRML
      PRML --> PRUP
      PRUP --> PRRD
      PRRD --> PRRS
      PRRS --> EXP2
      PRRS --> EXP3
      PRRS --> EXP1
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-traces stroke:#fbbf24,stroke-width:1px, color:#fbbf24,stroke-dasharray: 3 3;
Last Modified 2026/01/23

4.2 Attribute Processorのテスト

この演習では、Agent がエクスポートする前に、Spanデータから user.account_password削除し、user.phone_number 属性更新し、user.emailハッシュ化します。

Exercise

Gatewayを起動するGateway terminal ウィンドウで Gateway を起動します。

../otelcol --config=gateway.yaml

Agentを起動するAgent terminal ウィンドウで Agent を起動します。

../otelcol --config=agent.yaml

Load Generatorを起動するLoadgen terminal ウィンドウで loadgen を起動します

../loadgen -count 1

デバッグ出力を確認するAgentGateway の両方で、user.account_password が削除され、user.phone_numberuser.email が更新されていることを確認します

   -> user.name: Str(George Lucas)
   -> user.phone_number: Str(UNKNOWN NUMBER)
   -> user.email: Str(62d5e03d8fd5808e77aee5ebbd90cf7627a470ae0be9ffd10e8025a4ad0e1287)
   -> payment.amount: Double(51.71)
   -> user.visa: Str(4111 1111 1111 1111)
   -> user.amex: Str(3782 822463 10005)
   -> user.mastercard: Str(5555 5555 5555 4444)
    -> user.name: Str(George Lucas)
    -> user.phone_number: Str(+1555-867-5309)
    -> user.email: Str(george@deathstar.email)
    -> user.password: Str(LOTR>StarWars1-2-3)
    -> user.visa: Str(4111 1111 1111 1111)
    -> user.amex: Str(3782 822463 10005)
    -> user.mastercard: Str(5555 5555 5555 4444)
    -> payment.amount: Double(95.22)

ファイル出力を確認するjq を使用して、gateway-traces.outuser.account_password が削除され、user.phone_numberuser.email が更新されていることを検証します

jq '.resourceSpans[].scopeSpans[].spans[].attributes[] | select(.key == "user.password" or .key == "user.phone_number" or .key == "user.email") | {key: .key, value: .value.stringValue}' ./gateway-traces.out

user.account_password が削除され、user.phone_numberuser.email が更新されていることに注目してください

{
  "key": "user.phone_number",
  "value": "UNKNOWN NUMBER"
}
{
  "key": "user.email",
  "value": "62d5e03d8fd5808e77aee5ebbd90cf7627a470ae0be9ffd10e8025a4ad0e1287"
}
重要

AgentGateway プロセスを、それぞれのターミナルで Ctrl-C を押して停止してください。

Last Modified 2026/01/23

4.3 Redaction Processorのテスト

redaction プロセッサは、テレメトリーデータからどの属性と値を許可または削除するかを正確に制御できます。

この演習では、Agent がエクスポートする前に、Spanデータの user.visauser.mastercard の値を秘匿化します。

Exercise

Gatewayを起動するGateway terminal ウィンドウで Gateway を起動します。

../otelcol --config=gateway.yaml

redaction/redact プロセッサを有効にするAgent terminal ウィンドウで、agent.yaml を編集して前の演習で追加した # を削除します。

    traces:
      receivers:
      - otlp
      processors:
      - memory_limiter
      - attributes/update              # Update, hash, and remove attributes
      - redaction/redact               # Redact sensitive fields using regex
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - file
      - otlphttp

Agentを起動するAgent terminal ウィンドウで Agent を起動します。

../otelcol --config=agent.yaml

Load Generatorを起動するLoadgen terminal ウィンドウで loadgen を起動します

../loadgen -count 1

デバッグ出力を確認するAgentGateway の両方で、user.visauser.mastercard の値が更新されていることを確認します。user.amex 属性の値は、blocked_values に一致する正規表現パターンが追加されていないため、秘匿化されていないことに注意してください。

   -> user.name: Str(George Lucas)
   -> user.phone_number: Str(UNKNOWN NUMBER)
   -> user.email: Str(62d5e03d8fd5808e77aee5ebbd90cf7627a470ae0be9ffd10e8025a4ad0e1287)
   -> payment.amount: Double(69.71)
   -> user.visa: Str(****)
   -> user.amex: Str(3782 822463 10005)
   -> user.mastercard: Str(****)
   -> redaction.masked.keys: Str(user.mastercard,user.visa)
   -> redaction.masked.count: Int(2)
    -> user.name: Str(George Lucas)
    -> user.phone_number: Str(+1555-867-5309)
    -> user.email: Str(george@deathstar.email)
    -> user.password: Str(LOTR>StarWars1-2-3)
    -> user.visa: Str(4111 1111 1111 1111)
    -> user.amex: Str(3782 822463 10005)
    -> user.mastercard: Str(5555 5555 5555 4444)
    -> payment.amount: Double(65.54)
メモ

redaction プロセッサに summary:debug を含めると、デバッグ出力に、どの一致するキー値が秘匿化されたか、およびマスクされた値の数に関するサマリー情報が含まれます。

     -> redaction.masked.keys: Str(user.mastercard,user.visa)
     -> redaction.masked.count: Int(2)

ファイル出力を確認するjq を使用して、gateway-traces.outuser.visauser.mastercard が更新されていることを検証します。

jq '.resourceSpans[].scopeSpans[].spans[].attributes[] | select(.key == "user.visa" or .key == "user.mastercard" or .key == "user.amex") | {key: .key, value: .value.stringValue}' ./gateway-traces.out

blocked_values に一致する正規表現パターンが追加されていないため、user.amex は秘匿化されていないことに注意してください

{
  "key": "user.visa",
  "value": "****"
}
{
  "key": "user.amex",
  "value": "3782 822463 10005"
}
{
  "key": "user.mastercard",
  "value": "****"
}

これらは、attributesredaction プロセッサを設定して機密データを保護する方法のほんの一例です。

重要

AgentGateway プロセスを、それぞれのターミナルで Ctrl-C を押して停止してください。

Last Modified 2026/01/23

5. Transform Data

10 minutes  

Transform Processor を使用すると、パイプラインを流れるテレメトリデータ(ログ、メトリクス、トレース)を変更できます。OpenTelemetry Transformation Language (OTTL) を使用して、アプリケーションコードを変更することなく、データのフィルタリング、エンリッチメント、変換をその場で行うことができます。

この演習では、gateway.yaml を更新して、次の処理を行う Transform Processor を追加します

  • ログリソース属性の フィルタリング
  • JSON構造化ログデータの属性への パース
  • ログメッセージ本文に基づくログ重大度レベルの 設定

以前のログで SeverityTextSeverityNumber が未定義だったことにお気づきかもしれません。これは filelog レシーバーの典型的な動作です。ただし、重大度はログ本文内に埋め込まれています。例

SeverityText:
SeverityNumber: Unspecified(0)
Body: Str(2025-01-31 15:49:29 [WARN] - Do or do not, there is no try.)

ログには、ログ本文内にJSONとしてエンコードされた構造化データが含まれていることがよくあります。これらのフィールドを属性として抽出することで、インデックス作成、フィルタリング、クエリの効率が向上します。下流のシステムで手動でJSONをパースする代わりに、OTTLを使用してテレメトリパイプラインレベルで自動的に変換できます。

Exercise
重要

すべてのターミナルウィンドウを 5-transform-data ディレクトリに移動し、clear コマンドを実行してください。

4-sensitve-data ディレクトリから *.yaml5-transform-data にコピーします。更新後のディレクトリ構造は次のようになります

.
├── agent.yaml
└── gateway.yaml
Last Modified 2026/01/23

5. Transform Dataのサブセクション

5.1 Configuration

Exercise

transform プロセッサーを追加する: Gateway terminal ウィンドウに切り替え、gateway.yaml を編集して次の transform プロセッサーを追加します

  transform/logs:                      # Processor Type/Name
    log_statements:                    # Log Processing Statements
      - context: resource              # Log Context
        statements:                    # List of attribute keys to keep
          - keep_keys(attributes, ["com.splunk.sourcetype", "host.name", "otelcol.service.mode"])

-context: resource キーを使用することで、ログの resourceLog 属性をターゲットにしています。

この設定により、関連するリソース属性(com.splunk.sourcetypehost.nameotelcol.service.mode)のみが保持され、ログの効率が向上し、不要なメタデータが削減されます。

ログ重大度マッピング用のコンテキストブロックを追加する: ログレコードの severity_textseverity_number フィールドを適切に設定するために、log_statements 内に log コンテキストブロックを追加します。この設定では、ログ本文から level 値を抽出し、severity_text にマッピングし、ログレベルに基づいて対応する severity_number を割り当てます

      - context: log                   # Log Context
        statements:                    # Transform Statements Array
          - set(cache, ParseJSON(body)) where IsMatch(body, "^\\{")  # Parse JSON log body into a cache object
          - flatten(cache, "")                                        # Flatten nested JSON structure
          - merge_maps(attributes, cache, "upsert")                   # Merge cache into attributes, updating existing keys
          - set(severity_text, attributes["level"])                   # Set severity_text from the "level" attribute
          - set(severity_number, 1) where severity_text == "TRACE"    # Map severity_text to severity_number
          - set(severity_number, 5) where severity_text == "DEBUG"
          - set(severity_number, 9) where severity_text == "INFO"
          - set(severity_number, 13) where severity_text == "WARN"
          - set(severity_number, 17) where severity_text == "ERROR"
          - set(severity_number, 21) where severity_text == "FATAL"

merge_maps 関数は、2つのマップ(辞書)を1つに結合するために使用されます。この場合、cache オブジェクト(ログ本文からパースされたJSONデータを含む)を attributes マップにマージします。

  • パラメータ:
    • attributes: データがマージされるターゲットマップ
    • cache: パースされたJSONデータを含むソースマップ
    • "upsert": このモードは、attributes マップにすでにキーが存在する場合、その値が cache の値で更新されることを保証します。キーが存在しない場合は、挿入されます。

このステップは、ログ本文からのすべての関連フィールド(例:levelmessage など)が attributes マップに追加され、さらなる処理やエクスポートで利用可能になることを保証するため、非常に重要です。

主要な変換の概要:

  • Parse JSON: ログ本文から構造化データを抽出します。
  • Flatten JSON: ネストされたJSONオブジェクトをフラットな構造に変換します。
  • Merge Attributes: 抽出されたデータをログ属性に統合します。
  • Map Severity Text: ログの level 属性から severity_text を割り当てます。
  • Assign Severity Numbers: 重大度レベルを標準化された数値に変換します。
重要

resource 用のコンテキストブロックと log 用のコンテキストブロックの2つを含む 単一の transform プロセッサーが必要です。

この設定により、ログの重大度が正しく抽出、標準化され、効率的な処理のために構造化されます。

Tip

すべてのJSONフィールドをトップレベルの属性にマッピングするこの方法は、OTTLのテストとデバッグのみに使用してください。本番環境では高いカーディナリティが発生します。

logs パイプラインを更新する: logs: パイプラインに transform/logs: プロセッサーを追加し、設定が次のようになるようにします

    logs:                         # Logs pipeline
      receivers:
      - otlp                      # OTLP receiver
      processors:                 # Processors for logs
      - memory_limiter
      - resource/add_mode
      - transform/logs
      - batch
      exporters:
      - debug                     # Debug exporter
      - file/logs

https://otelbin.io を使用して Agent の設定を検証します。参考として、パイプラインの logs: セクションは次のようになります

%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
      REC1(&nbsp;&nbsp;otlp&nbsp;&nbsp;<br>fa:fa-download):::receiver
      PRO1(memory_limiter<br>fa:fa-microchip):::processor
      PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
      PRO4(transform<br>fa:fa-microchip<br>logs):::processor
      PRO5(batch<br>fa:fa-microchip):::processor
      EXP1(file<br>fa:fa-upload<br>logs):::exporter
      EXP2(&ensp;&ensp;debug&ensp;&ensp;<br>fa:fa-upload):::exporter
    %% Links
    subID1:::sub-logs
    subgraph " "
      subgraph subID1[**Logs**]
      direction LR
      REC1 --> PRO1
      PRO1 --> PRO3
      PRO3 --> PRO4
      PRO4 --> PRO5
      PRO5 --> EXP2
      PRO5 --> EXP1
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-logs stroke:#34d399,stroke-width:1px, color:#34d399,stroke-dasharray: 3 3;
Last Modified 2026/01/23

5.2 Setup Environment

Exercise

Gateway を起動する: Gateway terminal で以下を実行します

../otelcol --config=gateway.yaml

Agent を起動する: Agent terminal で以下を実行します

../otelcol --config=agent.yaml

Load Generator を起動する: Loadgen terminal ウィンドウで、次のコマンドを実行して JSON を有効にした Load Generator を起動します

../loadgen -logs -json -count 5

loadgen は JSON 形式で 5 行のログを ./quotes.log に書き込みます。

Last Modified 2026/01/23

5.3 Test Transform Processor

このテストでは、Agent によってエクスポートされる前に、com.splunk/sourceos.type のメタデータがログリソース属性から 削除 されていることを確認します。さらに、このテストでは以下を確認します

  1. 重大度情報を抽出するためにログ本文がパースされていること
    • SeverityTextSeverityNumberLogRecord に設定されていること
  2. ログ本文の JSON フィールドがログ attributes に昇格していること

これにより、エクスポート前に適切なメタデータフィルタリング、重大度マッピング、および構造化ログのエンリッチメントが行われることが保証されます。

Exercise

デバッグ出力を確認する: AgentGateway の両方で、com.splunk/sourceos.type が削除されていることを確認します

Resource attributes:
   -> com.splunk.sourcetype: Str(quotes)
   -> host.name: Str(workshop-instance)
   -> otelcol.service.mode: Str(agent)
Resource attributes:
   -> com.splunk.source: Str(./quotes.log)
   -> com.splunk.sourcetype: Str(quotes)
   -> host.name: Str(workshop-instance)
   -> os.type: Str(linux)
   -> otelcol.service.mode: Str(agent)

AgentGateway の両方で、LogRecordSeverityTextSeverityNumber がログ本文の重大度 level で定義されていることを確認します。また、本文の JSON フィールドがトップレベルのログ Attributes としてアクセスできることを確認します

<snip>
SeverityText: WARN
SeverityNumber: Warn(13)
Body: Str({"level":"WARN","message":"Your focus determines your reality.","movie":"SW","timestamp":"2025-03-07 11:17:26"})
Attributes:
     -> log.file.path: Str(quotes.log)
     -> level: Str(WARN)
     -> message: Str(Your focus determines your reality.)
     -> movie: Str(SW)
     -> timestamp: Str(2025-03-07 11:17:26)
</snip>
<snip>
SeverityText:
SeverityNumber: Unspecified(0)
Body: Str({"level":"WARN","message":"Your focus determines your reality.","movie":"SW","timestamp":"2025-03-07 11:17:26"})
Attributes:
     -> log.file.path: Str(quotes.log)
</snip>

ファイル出力を確認する: 新しい gateway-logs.out ファイルでデータが変換されていることを確認します

jq '[.resourceLogs[].scopeLogs[].logRecords[] | {severityText, severityNumber, body: .body.stringValue}]' gateway-logs.out
[
  {
    "severityText": "DEBUG",
    "severityNumber": 5,
    "body": "{\"level\":\"DEBUG\",\"message\":\"All we have to decide is what to do with the time that is given us.\",\"movie\":\"LOTR\",\"timestamp\":\"2025-03-07 11:56:29\"}"
  },
  {
    "severityText": "WARN",
    "severityNumber": 13,
    "body": "{\"level\":\"WARN\",\"message\":\"The Force will be with you. Always.\",\"movie\":\"SW\",\"timestamp\":\"2025-03-07 11:56:29\"}"
  },
  {
    "severityText": "ERROR",
    "severityNumber": 17,
    "body": "{\"level\":\"ERROR\",\"message\":\"One does not simply walk into Mordor.\",\"movie\":\"LOTR\",\"timestamp\":\"2025-03-07 11:56:29\"}"
  },
  {
    "severityText": "DEBUG",
    "severityNumber": 5,
    "body": "{\"level\":\"DEBUG\",\"message\":\"Do or do not, there is no try.\",\"movie\":\"SW\",\"timestamp\":\"2025-03-07 11:56:29\"}"
  }
]
[
  {
    "severityText": "ERROR",
    "severityNumber": 17,
    "body": "{\"level\":\"ERROR\",\"message\":\"There is some good in this world, and it's worth fighting for.\",\"movie\":\"LOTR\",\"timestamp\":\"2025-03-07 11:56:29\"}"
  }
]
重要

それぞれのターミナルで Ctrl-C を押して、AgentGateway のプロセスを停止してください。

Last Modified 2026/01/23

6. Routing Data

10 minutes  

OpenTelemetry の Routing Connector は、特定の条件に基づいてデータ(tracesmetrics、または logs)を異なるパイプライン/宛先に振り分けることができる強力な機能です。これは、テレメトリデータのサブセットに異なる処理やエクスポートロジックを適用したい場合に特に有用です。

例えば、本番環境 のデータを1つのエクスポーターに送信し、テスト開発 のデータを別のエクスポーターに振り分けることができます。同様に、サービス名、環境、スパン名などの属性に基づいて特定のスパンをルーティングし、カスタムの処理やストレージロジックを適用することもできます。

Exercise
重要

すべてのターミナルウィンドウを 6-routing-data ディレクトリに移動し、clear コマンドを実行してください。

5-transform-data ディレクトリから *.yaml6-routing-data にコピーします。更新後のディレクトリ構造は次のようになります

.
├── agent.yaml
└── gateway.yaml

次に、Routing Connector とそれぞれのパイプラインを設定します。

Last Modified 2026/01/23

6. Routing Dataのサブセクション

6.1 Configure the Routing Connector

この演習では、gateway.yamlRouting Connector を設定します。Routing Connector はメトリクス、トレース、ログを任意の属性に基づいてルーティングできますが、ここでは deployment.environment 属性に基づくトレースルーティングに焦点を当てます(ただし、任意のスパン/ログ/メトリクス属性を使用できます)。

Exercise

新しい file エクスポーターを追加する: routing コネクターには、ルーティング用に異なるターゲットが必要です。Gateway terminal で、gateway.yamlexporters セクションに 2 つの新しいファイルエクスポーター file/traces/route1-regularfile/traces/route2-security を作成し、データが正しく振り分けられるようにします

  file/traces/route1-regular:                     # Exporter for regular traces
    path: "./gateway-traces-route1-regular.out"   # Path for saving trace data
    append: false                                 # Overwrite the file each time
  file/traces/route2-security:                    # Exporter for security traces
    path: "./gateway-traces-route2-security.out"  # Path for saving trace data
    append: false                                 # Overwrite the file each time

ルーティングを有効にする: routing コネクターを追加します。OpenTelemetry の設定ファイルでは、connectors はレシーバーやプロセッサーと同様に専用のセクションを持っています。

#connectors: セクションを見つけてコメントを解除します。次に、connectors: セクションの下に以下を追加します

  routing:
    default_pipelines: [traces/route1-regular]  # Default pipeline if no rule matches
    error_mode: ignore                          # Ignore errors in routing
    table:                                      # Define routing rules
      # Routes spans to a target pipeline if the resourceSpan attribute matches the rule
      - statement: route() where attributes["deployment.environment"] == "security-applications"
        pipelines: [traces/route2-security]     # Security target pipeline

設定ファイルのデフォルトパイプラインは、キャッチオールとして機能します。ルーティングルールテーブルのルールに一致しないすべてのデータ(この場合はスパン)のルーティング先となります。このテーブルには、["deployment.environment"] == "security-applications" ルールに一致するスパンのターゲットパイプラインが定義されています。

routing の設定が完了したら、次のステップはこれらのルーティングルールを適用する pipelines を設定することです。

Last Modified 2026/01/23

6.2 Configuring the Pipelines

Exercise

元の traces パイプラインをルーティングを使用するように更新する:

  1. routing を有効にするには、元の traces パイプラインを更新して、routing のみをエクスポーターとして使用します。これにより、すべてのスパンデータが Routing Connector を経由して評価され、接続されたパイプラインに転送されます。また、すべての プロセッサーを削除し、空の配列([])に置き換えます。これは、traces/route1-regulartraces/route2-security パイプラインで処理されるようになり、各ルートに対してカスタム動作が可能になるためです。traces: の設定は次のようになります

    traces:                       # Traces pipeline
      receivers:
      - otlp                      # OTLP receiver
      processors: []              # Processors for traces
      exporters:
      - routing

既存の traces パイプラインの下に route1-regularroute2-security の両方のトレースパイプラインを追加する:

  1. Route1-regular パイプラインを設定する: このパイプラインは、コネクターのルーティングテーブルに一致しないすべてのスパンを処理します。 これは唯一のレシーバーとして routing を使用し、元の traces パイプラインからの connection を通じてデータを受信することに注意してください。

        traces/route1-regular:         # Default pipeline for unmatched spans
          receivers:
          - routing                    # Receive data from the routing connector
          processors:
          - memory_limiter             # Memory Limiter Processor
          - resource/add_mode          # Adds collector mode metadata
          - batch
          exporters:
          - debug                      # Debug Exporter
          - file/traces/route1-regular # File Exporter for unmatched spans
  2. route2-security パイプラインを追加する: このパイプラインは、ルーティングルールの "[deployment.environment"] == "security-applications" ルールに一致するすべてのスパンを処理します。このパイプラインもレシーバーとして routing を使用しています。このパイプラインを traces/route1-regular の下に追加します。

        traces/route2-security:         # Default pipeline for unmatched spans
          receivers:
          - routing                     # Receive data from the routing connector
          processors:
          - memory_limiter              # Memory Limiter Processor
          - resource/add_mode           # Adds collector mode metadata
          - batch
          exporters:
          - debug                       # Debug exporter
          - file/traces/route2-security # File exporter for unmatched spans

otelbin.io を使用して Agent の設定を検証します。参考として、パイプラインの traces: セクションは次のようになります

%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
      REC1(&nbsp;&nbsp;&nbsp;otlp&nbsp;&nbsp;&nbsp;<br>fa:fa-download):::receiver
      PRO1(memory_limiter<br>fa:fa-microchip):::processor
      PRO2(memory_limiter<br>fa:fa-microchip):::processor
      PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
      PRO4(resource<br>fa:fa-microchip<br>add_mode):::processor
      PRO5(batch<br>fa:fa-microchip):::processor
      PRO6(batch<br>fa:fa-microchip):::processor
      EXP1(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload):::exporter
      EXP2(&emsp;&emsp;file&emsp;&emsp;<br>fa:fa-upload<br>traces):::exporter
      EXP3(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload):::exporter
      EXP4(&emsp;&emsp;file&emsp;&emsp;<br>fa:fa-upload<br>traces):::exporter
      ROUTE1(&nbsp;routing&nbsp;<br>fa:fa-route):::con-export
      ROUTE2(&nbsp;routing&nbsp;<br>fa:fa-route):::con-receive
      ROUTE3(&nbsp;routing&nbsp;<br>fa:fa-route):::con-receive
    %% Links
    subID1:::sub-traces
    subID2:::sub-traces
    subID3:::sub-traces
    subgraph " "
    direction LR
      subgraph subID1[**Traces**]
      REC1 --> ROUTE1
      end
      subgraph subID2[**Traces/route2-security**]
      ROUTE1 --> ROUTE2
      ROUTE2 --> PRO1
      PRO1 --> PRO3
      PRO3 --> PRO5
      PRO5 --> EXP1
      PRO5 --> EXP2
      end
      subgraph subID3[**Traces/route1-regular**]
      ROUTE1 --> ROUTE3
      ROUTE3 --> PRO2
      PRO2 --> PRO4
      PRO4 --> PRO6
      PRO6 --> EXP3
      PRO6 --> EXP4
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-traces stroke:#fbbf24,stroke-width:1px, color:#fbbf24,stroke-dasharray: 3 3;
Last Modified 2026/01/23

6.3 Test Routing Connector

Exercise

このセクションでは、Gateway 用に設定した routing ルールをテストします。期待される結果は、"[deployment.environment"] == "security-applications" ルールに一致する loadgen によって生成された spangateway-traces-route2-security.out ファイルに送信されることです。

Gateway を起動する: Gateway terminal ウィンドウで Gateway を起動します。

../otelcol --config gateway.yaml

Agent を起動する: Agent terminal ウィンドウで Agent を起動します。

../otelcol --config agent.yaml

通常のスパンを送信する: Loadgen terminal ウィンドウで loadgen を使用して通常のスパンを送信します

../loadgen -count 1

AgentGateway の両方でデバッグ情報が表示されます。Gateway は新しい gateway-traces-route1-regular.out ファイルも生成します。これが通常のスパンの指定された宛先になりました。

Tip

gateway-traces-route1-regular.out を確認すると、loadgen によって送信された span が含まれています。また、空の gateway-traces-route2-security..out ファイルも表示されます。これは、ルーティング設定が、一致するスパンがまだ処理されていなくても、すぐに出力ファイルを作成するためです。

セキュリティスパンを送信する: Loadgen terminal ウィンドウで security フラグを使用してセキュリティスパンを送信します

../loadgen -security -count 1

再び、AgentGateway の両方で、送信したスパンを含むデバッグ情報が表示されるはずです。今回は、Gatewaygateway-traces-route2-security.out ファイルに行を書き込みます。これは、deployment.environment リソース属性が "security-applications" に一致するスパン用に指定されたファイルです。

jq -c '.resourceSpans[] as $resource | $resource.scopeSpans[].spans[] | {spanId: .spanId, deploymentEnvironment: ($resource.resource.attributes[] | select(.key == "deployment.environment") | .value.stringValue)}' gateway-traces-route2-security.out
{"spanId":"cb799e92e26d5782","deploymentEnvironment":"security-applications"}

このシナリオを複数回繰り返すことができ、各トレースは対応する出力ファイルに書き込まれます。

重要

それぞれのターミナルで Ctrl-C を押して、AgentGateway のプロセスを停止してください。

まとめ

このセクションでは、異なるスパンを送信し、その宛先を確認することで、Gateway のルーティングコネクターを正常にテストしました。

  • 通常のスパンgateway-traces-route1-regular.out に正しくルーティングされ、一致する deployment.environment 属性を持たないスパンがデフォルトパイプラインに従うことが確認されました。

  • セキュリティ関連のスパンgateway-traces-route2-security.out にルーティングされ、"deployment.environment": "security-applications" に基づくルーティングルールが期待どおりに機能することが実証されました。

出力ファイルを検査することで、OpenTelemetry Collector が スパン属性を正しく評価し、適切な宛先にルーティングしている ことを確認しました。これにより、ルーティングルールが異なるユースケース向けにテレメトリデータを効果的に分離して振り分けることができることが検証されました。

追加のルーティングルールを定義して、異なる属性に基づいてスパン、メトリクス、ログをさらに分類することで、このアプローチを拡張できます。

Last Modified 2026/01/23

7. Count Connector でメトリクスを作成する

10 minutes  

このセクションでは、Count Connector を使用して、ログから属性値を抽出し、意味のあるメトリクスに変換する方法を説明します。

具体的には、Count Connector を使用して、ログに出現する「Star Wars」と「Lord of the Rings」の名言の数を追跡し、測定可能なデータポイントに変換します。

Exercise
重要

すべてのターミナルウィンドウを 7-sum-count ディレクトリに変更し、clear コマンドを実行してください。

6-routing-data ディレクトリから *.yaml7-sum-count にコピーしてください。更新後のディレクトリ構造は以下のようになります

.
├── agent.yaml
└── gateway.yaml
  • agent.yaml を更新して、ログを読み取る頻度を変更します。 agent.yaml 内の filelog/quotes レシーバーを見つけ、poll_interval 属性を追加してください
  filelog/quotes:                      # Receiver Type/Name
    poll_interval: 10s                 # Only read every ten seconds

遅延を設定する理由は、OpenTelemetry Collector の Count Connector が各処理インターバル内でのみログをカウントするためです。つまり、データが読み取られるたびに、次のインターバルでカウントがゼロにリセットされます。デフォルトの Filelog receiver インターバル 200ms では、loadgen が書き込むすべての行を読み取り、カウントが1になります。このインターバルを設定することで、複数のエントリをカウントできるようになります。

以下に示すように、条件を省略することで、Collector は各読み取りインターバルの累計カウントを維持できます。ただし、バックエンドは長期間にわたってカウントを追跡できるため、累計カウントはバックエンドに任せるのがベストプラクティスです。

Exercise
  • Count Connector を追加する

設定の connectors セクションに Count Connector を追加し、使用するメトリクスカウンターを定義します

connectors:
  count:
    logs:
      logs.full.count:
        description: "Running count of all logs read in interval"
      logs.sw.count:
        description: "StarWarsCount"
        conditions:
        - attributes["movie"] == "SW"
      logs.lotr.count:
        description: "LOTRCount"
        conditions:
        - attributes["movie"] == "LOTR"
      logs.error.count:
        description: "ErrorCount"
        conditions:
        - attributes["level"] == "ERROR"
  • メトリクスカウンターの説明

    • logs.full.count:各読み取りインターバルで処理されたログの総数を追跡します。 このメトリクスにはフィルタリング条件がないため、システムを通過するすべてのログがカウントに含まれます。
    • logs.sw.count:Star Wars 映画の名言を含むログをカウントします。
    • logs.lotr.count:Lord of the Rings 映画の名言を含むログをカウントします。
    • logs.error.count:読み取りインターバルで重大度レベルが ERROR のログをカウントする、実際のシナリオを表します。
  • パイプラインで Count Connector を設定する 以下のパイプライン設定では、connector exporter が logs セクションに追加され、connector receiver が metrics セクションに追加されています。

  pipelines:
    traces:
      receivers:
      - otlp
      processors:
      - memory_limiter
      - attributes/update              # Update, hash, and remove attributes
      - redaction/redact               # Redact sensitive fields using regex
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - file
      - otlphttp
    metrics:
      receivers:
      - count                           # Count Connector that receives count metric from logs count exporter in logs pipeline.
      - otlp
      #- hostmetrics                    # Host Metrics Receiver
      processors:
      - memory_limiter
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - otlphttp
    logs:
      receivers:
      - otlp
      - filelog/quotes
      processors:
      - memory_limiter
      - resourcedetection
      - resource/add_mode
      - transform/logs                 # Transform logs processor
      - batch
      exporters:
      - count                          # Count Connector that exports count as a metric to metrics pipeline.
      - debug
      - otlphttp

ログは属性に基づいてカウントされます。ログデータが属性ではなくログボディに格納されている場合は、パイプラインで Transform プロセッサーを使用して、キー/バリューのペアを抽出し、属性として追加する必要があります。

このワークショップでは、05-transform-data セクションで既に merge_maps(attributes, cache, "upsert") を追加しています。これにより、関連するすべてのデータが処理用のログ属性に含まれるようになります。

属性を作成するフィールドを選択する際は注意が必要です。すべてのフィールドを無差別に追加することは、本番環境では一般的に理想的ではありません。不要なデータの乱雑さを避けるため、本当に必要なフィールドのみを選択してください。

Exercise
  • otelbin.io を使用して agent 設定を検証してください。参考として、パイプラインの logsmetrics: セクションは以下のようになります
%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
    REC1(otlp<br>fa:fa-download):::receiver
    REC2(filelog<br>fa:fa-download<br>quotes):::receiver
    REC3(otlp<br>fa:fa-download):::receiver
    PRO1(memory_limiter<br>fa:fa-microchip):::processor
    PRO2(memory_limiter<br>fa:fa-microchip):::processor
    PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
    PRO4(resource<br>fa:fa-microchip<br>add_mode):::processor
    PRO5(batch<br>fa:fa-microchip):::processor
    PRO6(batch<br>fa:fa-microchip):::processor
    PRO7(resourcedetection<br>fa:fa-microchip):::processor
    PRO8(resourcedetection<br>fa:fa-microchip):::processor
    PRO9(transfrom<br>fa:fa-microchip<br>logs):::processor
    EXP1(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload):::exporter
    EXP2(&emsp;&emsp;otlphttp&emsp;&emsp;<br>fa:fa-upload):::exporter
    EXP3(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload):::exporter
    EXP4(&emsp;&emsp;otlphttp&emsp;&emsp;<br>fa:fa-upload):::exporter
    ROUTE1(&nbsp;count&nbsp;<br>fa:fa-route):::con-export
    ROUTE2(&nbsp;count&nbsp;<br>fa:fa-route):::con-receive

    %% Links
    subID1:::sub-logs
    subID2:::sub-metrics
    subgraph " "
      direction LR
      subgraph subID1[**Logs**]
      direction LR
      REC1 --> PRO1
      REC2 --> PRO1
      PRO1 --> PRO7
      PRO7 --> PRO3
      PRO3 --> PRO9
      PRO9 --> PRO5
      PRO5 --> ROUTE1
      PRO5 --> EXP1
      PRO5 --> EXP2
      end

      subgraph subID2[**Metrics**]
      direction LR
      ROUTE1 --> ROUTE2
      ROUTE2 --> PRO2
      REC3 --> PRO2
      PRO2 --> PRO8
      PRO8 --> PRO4
      PRO4 --> PRO6
      PRO6 --> EXP3
      PRO6 --> EXP4
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-logs stroke:#34d399,stroke-width:1px, color:#34d399,stroke-dasharray: 3 3;
classDef sub-metrics stroke:#38bdf8,stroke-width:1px, color:#38bdf8,stroke-dasharray: 3 3;
Last Modified 2026/01/23

7. Count & Sum Connectorのサブセクション

7.1 Count Connector のテスト

Exercise

Gateway を起動する Gateway terminal ウィンドウで以下を実行します

../otelcol --config=gateway.yaml

Agent を起動する Agent terminal ウィンドウで以下を実行します

../otelcol --config=agent.yaml

Loadgen で12行のログを送信する Spans terminal ウィンドウで、12行のログを送信します。これらは2つのインターバルで読み取られるはずです。以下の loadgen コマンドを実行してください

../loadgen -logs -json -count 12

AgentGateway の両方がデバッグ情報を表示し、データを処理していることを示します。loadgen が完了するまで待ちます。

メトリクスが生成されたことを確認する ログが処理されると、Agent がメトリクスを生成して Gateway に転送し、Gateway がそれらを gateway-metrics.out に書き込みます。

出力に logs.full.countlogs.sw.countlogs.lotr.countlogs.error.count のメトリクスが含まれているか確認するには、以下の jq クエリを実行します

jq '.resourceMetrics[].scopeMetrics[].metrics[]
    | select(.name == "logs.full.count" or .name == "logs.sw.count" or .name == "logs.lotr.count" or .name == "logs.error.count")
    | {name: .name, value: (.sum.dataPoints[0].asInt // "-")}' gateway-metrics.out
{
  "name": "logs.sw.count",
  "value": "2"
}
{
  "name": "logs.lotr.count",
  "value": "2"
}
{
  "name": "logs.full.count",
  "value": "4"
}
{
  "name": "logs.error.count",
  "value": "2"
}
{
  "name": "logs.error.count",
  "value": "1"
}
{
  "name": "logs.sw.count",
  "value": "2"
}
{
  "name": "logs.lotr.count",
  "value": "6"
}
{
  "name": "logs.full.count",
  "value": "8"
}
Tip

注:logs.full.count は通常 logs.sw.count + logs.lotr.count と等しくなりますが、logs.error.count はランダムな数値になります。

重要

それぞれのターミナルで Ctrl-C を押して AgentGateway のプロセスを停止してください。

Last Modified 2026/01/23

7.2 Sum Connector でメトリクスを作成する

10 minutes  

このセクションでは、Sum Connector がスパンから値を抽出してメトリクスに変換する方法を説明します。

具体的には、ベーススパンからクレジットカードの請求額を取得し、Sum Connector を活用して合計請求額をメトリクスとして取得します。

この connector は、スパン、スパンイベント、メトリクス、データポイント、およびログレコードから属性値を収集(sum)するために使用できます。各個別の値をキャプチャし、メトリクスに変換して転送します。ただし、これらのメトリクスと属性を使用して計算やさらなる処理を行うのはバックエンドの役割です。

Exercise

Agent terminal ウィンドウに切り替えて、エディターで agent.yaml ファイルを開きます。

  • Sum Connector を追加する 設定の connectors セクションに Sum Connector を追加し、メトリクスカウンターを定義します
  sum:
    spans:
       user.card-charge:
        source_attribute: payment.amount
        conditions:
          - attributes["payment.amount"] != "NULL"
        attributes:
          - key: user.name

上記の例では、スパン内の payment.amount 属性をチェックしています。有効な値がある場合、Sum connector は user.card-charge というメトリクスを生成し、user.name を属性として含めます。これにより、バックエンドは請求サイクルなどの長期間にわたってユーザーの合計請求額を追跡して表示できます。

以下のパイプライン設定では、connector exporter が traces セクションに追加され、connector receiver が metrics セクションに追加されています。

Exercise
  • パイプラインで Count Connector を設定する
  pipelines:
    traces:
      receivers:
      - otlp
      processors:
      - memory_limiter
      - attributes/update              # Update, hash, and remove attributes
      - redaction/redact               # Redact sensitive fields using regex
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - file
      - otlphttp
      - sum                            # Sum connector which aggregates payment.amount from spans and sends to metrics pipeline
    metrics:
      receivers:
      - sum                            # Receives metrics from the sum exporter in the traces pipeline
      - count                          # Receives count metric from logs count exporter in logs pipeline.
      - otlp
      #- hostmetrics                   # Host Metrics Receiver
      processors:
      - memory_limiter
      - resourcedetection
      - resource/add_mode
      - batch
      exporters:
      - debug
      - otlphttp
    logs:
      receivers:
      - otlp
      - filelog/quotes
      processors:
      - memory_limiter
      - resourcedetection
      - resource/add_mode
      - transform/logs                 # Transform logs processor
      - batch
      exporters:
      - count                          # Count Connector that exports count as a metric to metrics pipeline.
      - debug
      - otlphttp
  • otelbin.io を使用して agent 設定を検証してください。参考として、パイプラインの tracesmetrics: セクションは以下のようになります
%%{init:{"fontFamily":"monospace"}}%%
graph LR
    %% Nodes
    REC1(otlp<br>fa:fa-download<br> ):::receiver
    REC3(otlp<br>fa:fa-download<br> ):::receiver
    PRO1(memory_limiter<br>fa:fa-microchip<br> ):::processor
    PRO2(memory_limiter<br>fa:fa-microchip<br> ):::processor
    PRO3(resource<br>fa:fa-microchip<br>add_mode):::processor
    PRO4(resource<br>fa:fa-microchip<br>add_mode):::processor
    PRO5(batch<br>fa:fa-microchip<br> ):::processor
    PRO6(batch<br>fa:fa-microchip<br> ):::processor
    PRO7(resourcedetection<br>fa:fa-microchip<br> ):::processor
    PRO8(resourcedetection<br>fa:fa-microchip<br>):::processor

    PROA(attributes<br>fa:fa-microchip<br>redact):::processor
    PROB(redaction<br>fa:fa-microchip<br>update):::processor
    EXP1(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload<br> ):::exporter
    EXP2(&emsp;&emsp;file&emsp;&emsp;<br>fa:fa-upload<br> ):::exporter
    EXP3(&nbsp;&ensp;debug&nbsp;&ensp;<br>fa:fa-upload<br> ):::exporter
    EXP4(&emsp;&emsp;otlphttp&emsp;&emsp;<br>fa:fa-upload<br> ):::exporter
    EXP5(&emsp;&emsp;otlphttp&emsp;&emsp;<br>fa:fa-upload<br> ):::exporter
    ROUTE1(&nbsp;sum&nbsp;<br>fa:fa-route<br> ):::con-export
    ROUTE2(&nbsp;count&nbsp;<br>fa:fa-route<br> ):::con-receive
    ROUTE3(&nbsp;sum&nbsp;<br>fa:fa-route<br> ):::con-receive

    %% Links
    subID1:::sub-traces
    subID2:::sub-metrics
    subgraph " "
      direction LR
      subgraph subID1[**Traces**]
      direction LR
      REC1 --> PRO1
      PRO1 --> PROA
      PROA --> PROB
      PROB --> PRO7
      PRO7 --> PRO3
      PRO3 --> PRO5
      PRO5 --> EXP1
      PRO5 --> EXP2
      PRO5 --> EXP5
      PRO5 --> ROUTE1
      end

      subgraph subID2[**Metrics**]
      direction LR
      ROUTE1 --> ROUTE3
      ROUTE3 --> PRO2
      ROUTE2 --> PRO2
      REC3 --> PRO2
      PRO2 --> PRO8
      PRO8 --> PRO4
      PRO4 --> PRO6
      PRO6 --> EXP3
      PRO6 --> EXP4
      end
    end
classDef receiver,exporter fill:#8b5cf6,stroke:#333,stroke-width:1px,color:#fff;
classDef processor fill:#6366f1,stroke:#333,stroke-width:1px,color:#fff;
classDef con-receive,con-export fill:#45c175,stroke:#333,stroke-width:1px,color:#fff;
classDef sub-logs stroke:#34d399,stroke-width:1px, color:#34d399,stroke-dasharray: 3 3;
classDef sub-traces stroke:#fbbf24,stroke-width:1px, color:#fbbf24,stroke-dasharray: 3 3;
classDef sub-metrics stroke:#38bdf8,stroke-width:1px, color:#38bdf8,stroke-dasharray: 3 3;
Last Modified 2026/01/23

7.3 Sum Connector のテスト

Exercise

Gateway を起動する Gateway terminal ウィンドウで以下を実行します

../otelcol --config=gateway.yaml

Agent を起動する Agent terminal ウィンドウで以下を実行します

../otelcol --config=agent.yaml

Loadgen を起動する Spans terminal ウィンドウで、以下の loadgen コマンドを使用して8つのスパンを送信します

../loadgen -count 8

AgentGateway の両方がデバッグ情報を表示し、データを処理していることを示します。loadgen が完了するまで待ちます。

メトリクスを確認する スパンを処理する際、Agent はメトリクスを生成して Gateway に転送します。Gateway はそれらを gateway-metrics.out に書き込みます。

メトリクス出力に user.card-charge が存在し、それぞれに user.name 属性があることを確認するには、以下の jq クエリを実行します

jq -r '.resourceMetrics[].scopeMetrics[].metrics[] | select(.name == "user.card-charge") | .sum.dataPoints[] | "\(.attributes[] | select(.key == "user.name").value.stringValue)\t\(.asDouble)"' gateway-metrics.out | while IFS=$'\t' read -r name charge; do
    printf "%-20s %s\n" "$name" "$charge"
done
George Lucas         67.49
Frodo Baggins        87.14
Thorin Oakenshield   90.98
Luke Skywalker       51.37
Luke Skywalker       65.56
Thorin Oakenshield   67.5
Thorin Oakenshield   66.66
Peter Jackson        94.39
重要

それぞれのターミナルで Ctrl-C を押して AgentGateway のプロセスを停止してください。

Last Modified 2026/01/23

8. まとめ

Well done Well done

Last Modified 2026/01/09

Splunk Synthetic Scripting

45 minutes   Author Robert Castley

問題がユーザーに影響を与える前に、Web アプリケーションのパフォーマンスをプロアクティブにモニタリングします。Splunk Synthetic Monitoring を使用すると、技術チームとビジネスチームは詳細なテストを作成し、開発サイクルのあらゆる段階で Web サイト、Web アプリケーション、リソースの速度と信頼性を継続的にモニタリングできます。

Splunk Synthetic Monitoring は、唯一の完全なオブザーバビリティスイートである Splunk Observability Cloud の一部として、稼働時間と Web パフォーマンス最適化のための最も包括的で詳細な機能を提供します。

API、サービスエンドポイント、エンドユーザーエクスペリエンスのモニタリングを簡単にセットアップできます。Splunk Synthetic Monitoring を使用すると、基本的な稼働時間とパフォーマンスモニタリングを超えて、問題のプロアクティブな検出と修正、Web パフォーマンスの最適化、顧客への最高のユーザーエクスペリエンス提供に集中できます。

Splunk Synthetic Monitoring では以下のことが可能です:

  • 重要なユーザーフロー、ビジネストランザクション、API エンドポイント全体で問題を迅速に検出・解決
  • インテリジェントな Web 最適化エンジンにより、Web パフォーマンスの問題が顧客に影響を与える前に防止
  • すべてのページリソースとサードパーティ依存関係のパフォーマンスを改善
Last Modified 2026/01/05

Splunk Synthetic Scriptingのサブセクション

1. Real Browser Test

はじめに

このワークショップでは、Chrome DevTools Recorder を使用して、Splunk デモインスタンスに対する Synthetic トランザクションを作成する方法を説明します。

Chrome DevTools Recorder からエクスポートした JSON を使用して、Splunk Synthetic Monitoring の Real Browser Test を作成します。

また、API TestUptime Test など、他の Splunk Synthetic Monitoring チェックについても学びます。

前提条件

  • Google Chrome ブラウザがインストールされていること
  • Splunk Observability Cloud へのアクセス権があること
Last Modified 2026/01/05

1. Real Browser Testのサブセクション

1.1 テストの記録

開始 URL を開く

ワークショップの開始 URL を Chrome で開きます。以下の適切なリンクをクリックして、新しいタブでサイトを開きます。

メモ

ワークショップの開始 URL は EMEAAMER/APAC で異なります。お住まいの地域に応じて正しい URL を使用してください。

Chrome DevTools Recorder を開く

次に、(上記で開いた新しいタブで)Developer Tools を開きます。Windows では Ctrl + Shift + I、Mac では Cmd + Option + I を押し、トップレベルメニューまたは More tools フライアウトメニューから Recorder を選択します。

Open Recorder Open Recorder

注意

サイトの要素はビューポートの幅によって変わる場合があります。記録する前に、作成するテストの種類(デスクトップ、タブレット、モバイル)に応じてブラウザウィンドウを適切な幅に設定してください。必要に応じて、DevTools の「dock side」を別ウィンドウとしてポップアウトさせると便利です。

新しい記録を作成

DevTools ウィンドウで Recorder パネルを開いた状態で、Create a new recording ボタンをクリックして開始します。

Recorder Recorder

Recording Name には、イニシャルを接頭辞として使用します(例: <your initials> - Online Boutique)。Start Recording をクリックして、アクションの記録を開始します。

Recording Name Recording Name

記録が開始されたら、サイトで以下のアクションを実行します:

  • Vintage Camera Lens をクリック
  • Add to Cart をクリック
  • Place Order をクリック
  • Recorder パネルの End recording をクリック

End Recording End Recording

記録のエクスポート

Export ボタンをクリックします:

Export button Export button

フォーマットとして JSON を選択し、Save をクリックします。

Export JSON Export JSON

Save JSON Save JSON

おめでとうございます! Chrome DevTools Recorder を使用した記録の作成に成功しました。次に、この記録を使用して Splunk Synthetic Monitoring で Real Browser Test を作成します。


JSON ファイルを表示するにはここをクリック
{
    "title": "RWC - Online Boutique",
    "steps": [
        {
            "type": "setViewport",
            "width": 1430,
            "height": 1016,
            "deviceScaleFactor": 1,
            "isMobile": false,
            "hasTouch": false,
            "isLandscape": false
        },
        {
            "type": "navigate",
            "url": "https://online-boutique-eu.splunko11y.com/",
            "assertedEvents": [
                {
                    "type": "navigation",
                    "url": "https://online-boutique-eu.splunko11y.com/",
                    "title": "Online Boutique"
                }
            ]
        },
        {
            "type": "click",
            "target": "main",
            "selectors": [
                [
                    "div:nth-of-type(2) > div:nth-of-type(2) a > div"
                ],
                [
                    "xpath//html/body/main/div/div/div[2]/div[2]/div/a/div"
                ],
                [
                    "pierce/div:nth-of-type(2) > div:nth-of-type(2) a > div"
                ]
            ],
            "offsetY": 170,
            "offsetX": 180,
            "assertedEvents": [
                {
                    "type": "navigation",
                    "url": "https://online-boutique-eu.splunko11y.com/product/66VCHSJNUP",
                    "title": ""
                }
            ]
        },
        {
            "type": "click",
            "target": "main",
            "selectors": [
                [
                    "aria/ADD TO CART"
                ],
                [
                    "button"
                ],
                [
                    "xpath//html/body/main/div[1]/div/div[2]/div/form/div/button"
                ],
                [
                    "pierce/button"
                ],
                [
                    "text/Add to Cart"
                ]
            ],
            "offsetY": 35.0078125,
            "offsetX": 46.4140625,
            "assertedEvents": [
                {
                    "type": "navigation",
                    "url": "https://online-boutique-eu.splunko11y.com/cart",
                    "title": ""
                }
            ]
        },
        {
            "type": "click",
            "target": "main",
            "selectors": [
                [
                    "aria/PLACE ORDER"
                ],
                [
                    "div > div > div.py-3 button"
                ],
                [
                    "xpath//html/body/main/div/div/div[4]/div/form/div[4]/button"
                ],
                [
                    "pierce/div > div > div.py-3 button"
                ],
                [
                    "text/Place order"
                ]
            ],
            "offsetY": 29.8125,
            "offsetX": 66.8203125,
            "assertedEvents": [
                {
                    "type": "navigation",
                    "url": "https://online-boutique-eu.splunko11y.com/cart/checkout",
                    "title": ""
                }
            ]
        }
    ]
}
Last Modified 2026/01/05

1.2 Real Browser Test の作成

Splunk Observability Cloud で Synthetics に移動し、Add new test をクリックします。

ドロップダウンから Browser test を選択します。

Add new test Add new test

Browser test content 設定ページが表示されます。

New Test New Test

Last Modified 2026/01/05

1.3 JSON のインポート

テストの設定を開始するには、Chrome DevTools Recorder からエクスポートした JSON をインポートする必要があります。Import ボタンを有効にするには、まずテストに名前を付ける必要があります(例: <your initials> - Online Boutique)。

Import Import

Import ボタンが有効になったら、クリックして Chrome DevTools Recorder からエクスポートした JSON ファイルをドロップするか、ファイルをアップロードします。

Import JSON Import JSON

JSON ファイルがアップロードされたら、Continue to edit steps をクリックします。

Import Complete Import Complete

Edit Steps Edit Steps

テストを編集する前に、まず設定を構成します。< Return to test をクリックします。

Last Modified 2026/01/05

1.4 設定

シンプル設定では、テストの基本を構成できます:

  • Name: テストの名前(例: RWC - Online Boutique)
  • Details:
    • Locations: テストを実行するロケーション
    • Device: 異なるデバイスと接続速度をエミュレート。選択したデバイスに合わせてビューポートも調整されます
    • Frequency: テストの実行頻度
    • Round-robin: 複数のロケーションを選択した場合、すべてのロケーションで同時に実行するのではなく、一度に1つのロケーションからテストを実行します
    • Active: テストをアクティブまたは非アクティブに設定

![Return to Test]このワークショップでは、モニタリングを行うロケーションを設定します。Locations フィールドをクリックすると、グローバルロケーションのリスト(合計50以上)が表示されます。

Global Locations Global Locations

以下のロケーションを選択します:

  • AWS - N. Virginia
  • AWS - London
  • AWS - Melbourne

完了したら、下にスクロールして Submit をクリックしてテストを保存します。

これで、選択した3つのロケーションから5分ごとにテストが実行されるようスケジュールされます。スケジュールの作成には数分かかります。

テストのスケジュール作成を待つ間、Edit test をクリックして Advanced 設定を確認しましょう。

Last Modified 2026/01/05

1.5 Advanced 設定

Advanced をクリックします。これらの設定はオプションで、テストをさらに詳細に構成するために使用できます。

メモ

このワークショップでは、これらの設定は情報提供のみを目的としており、実際には使用しません。

Advanced Settings Advanced Settings

  • Security:
    • TLS/SSL validation: 有効にすると、SSL/TLS 証明書の有効期限切れ、無効なホスト名、信頼できない発行者の検証を強制します
    • Authentication: 企業ネットワーク内など、追加のセキュリティプロトコルを必要とするサイトで認証するための資格情報を追加します。Authentication フィールドで concealed global variables を使用することで、資格情報のセキュリティレイヤーを追加し、チェック間で資格情報を共有しやすくなります
  • Custom Content:
    • Custom headers: 各リクエストで送信するカスタムヘッダーを指定します。たとえば、リクエストに特定のヘッダーを送信することで、バックエンドの分析からリクエストを除外するヘッダーを追加できます。カスタムヘッダーを使用して Cookie を設定することもできます
    • Cookies: テスト開始前にブラウザに Cookie を設定します。たとえば、ポップアップモーダルがランダムに表示されてテストに干渉するのを防ぐために Cookie を設定できます。設定された Cookie は、チェックの開始 URL のドメインに適用されます。Splunk Synthetics Monitoring は public suffix list を使用してドメインを判定します
    • Host overrides: あるホストから別のホストにリクエストをリルーティングするホストオーバーライドルールを追加します。たとえば、既存の本番サイトを開発サイトや特定の CDN エッジノードから読み込まれたページリソースに対してテストするホストオーバーライドを作成できます

次に、テストステップを編集して、各ステップにより意味のある名前を付けます。

Last Modified 2026/01/05

1.6 テストステップの編集

ステップを編集するには、+ Edit steps or synthetic transactions ボタンをクリックします。ここから、各ステップに意味のある名前を付けていきます。

Edit steps Edit steps

4つのステップそれぞれに意味のある名前を付けます。

  • Step 1: Go to URL というテキストを HomePage - Online Boutique に置き換えます
  • Step 2: Select Vintage Camera Lens と入力します
  • Step 3: Add to Cart と入力します
  • Step 4: Place Order と入力します

Step names Step names

< Return to test をクリックしてテスト設定ページに戻り、Save をクリックしてテストを保存します。

テストダッシュボードに戻り、テスト結果が表示され始めます。

Scatterplot Scatterplot

おめでとうございます! Splunk Synthetic Monitoring で Real Browser Test の作成に成功しました。次に、テスト結果をより詳しく見ていきます。

Last Modified 2026/01/05

1.7 テスト結果の表示

前のステップの散布図で、いずれかのドットをクリックしてテスト実行データにドリルダウンします。できれば、最新のテスト実行(最も右側)を選択してください。

Drilldown Drilldown

Last Modified 2026/01/05

API Test

API Test は、API エンドポイントの機能とパフォーマンスを柔軟にチェックする方法を提供します。API ファーストの開発へのシフトにより、フロントエンドのコア機能を提供するバックエンドサービスをモニタリングする必要性が高まっています。

マルチステップの API インタラクションのテストに興味がある場合でも、エンドポイントのパフォーマンスを可視化したい場合でも、API Test は目標の達成を支援します。

API test result API test result

Last Modified 2026/01/05

2. API Testのサブセクション

Global Variables

Global Variables

API テストを実行するために使用するグローバル変数を確認します。歯車アイコンの下にある Global Variables をクリックします。env.encoded_auth という名前のグローバル変数を使用して、Spotify API トランザクションを構築します。

placeholder placeholder

Last Modified 2026/01/05

新しい API テストの作成

新しい API テストを作成

Add new test ボタンをクリックし、ドロップダウンから API test を選択して新しい API テストを作成します。テスト名には イニシャル に続けて Spotify API と入力します(例: RWC - Spotify API)。

placeholder placeholder

Last Modified 2026/01/05

認証リクエスト

認証リクエストの追加

+ Add requests をクリックし、リクエストステップ名を入力します(例: Authenticate with Spotify API)。

placeholder placeholder

Request セクションを展開し、ドロップダウンからリクエストメソッドを POST に変更して、以下の URL を入力します:

https://accounts.spotify.com/api/token

Payload body セクションに以下を入力します:

grant_type=client_credentials

次に、以下のキー/値のペアで2つのリクエストヘッダーを追加します:

  • CONTENT-TYPE: application/x-www-form-urlencoded
  • AUTHORIZATION: Basic {{env.encoded_auth}}

Validation セクションを展開し、以下の抽出を追加します:

  • Extract from Response body JSON $.access_token as access_token

これにより、Spotify API から受信した JSON ペイロードを解析し、アクセストークンを抽出してカスタム変数として保存します。

Add payload token Add payload token

Last Modified 2026/01/05

検索リクエスト

検索リクエストの追加

+ Add Request をクリックして次のステップを追加します。ステップ名を Search for Tracks named “Up around the bend” とします。

Request セクションを展開し、リクエストメソッドを GET に変更して、以下の URL を入力します:

https://api.spotify.com/v1/search?q=Up%20around%20the%20bend&type=track&offset=0&limit=5

次に、以下のキー/値のペアで2つのリクエストヘッダーを追加します:

  • CONTENT-TYPE: application/json
  • AUTHORIZATION: Bearer {{custom.access_token}}

Add search request Add search request

Validation セクションを展開し、以下の抽出を追加します:

  • Extract from Response body JSON $.tracks.items[0].id as track.id

Add search payload Add search payload

< Return to test をクリックしてテスト設定ページに戻ります。次に Save をクリックして API テストを保存します。

Last Modified 2026/01/05

結果の表示

結果の表示

テストがプロビジョニングされて実行されるまで数分待ちます。テストが正常に実行されたら、実行をクリックしてテスト結果を表示します:

API test result API test result

6. リソース

Last Modified 2026/01/05

AWS Lambda関数の分散トレーシング

45 minutes   Author Guy-Francis Kono

このワークショップでは、AWS Lambda で実行される小規模なサーバーレスアプリケーションの分散トレースを構築し、AWS Kinesis を介してメッセージを produce および consume する方法を学びます。

まず、OpenTelemetry の自動計装がどのようにトレースをキャプチャし、選択した宛先にエクスポートするかを確認します。

次に、手動計装によってコンテキスト伝播を有効にする方法を見ていきます。

このワークショップのために、Splunk は AWS/EC2 上の Ubuntu Linux インスタンスを事前に構成しています。このインスタンスにアクセスするには、ワークショップインストラクターが提供する URL にアクセスしてください。

Last Modified 2025/05/29

Lambdaトレーシングのサブセクション

セットアップ

手動計装されていないLambdaアプリケーション 手動計装されていないLambdaアプリケーション

前提条件

Observability ワークショップインスタンス

Observability ワークショップは、多くの場合、Splunk が提供する事前設定済みの Ubuntu EC2 インスタンス上で実施されます。

ワークショップのインストラクターから、割り当てられたワークショップインスタンスの認証情報が提供されます。

インスタンスには以下の環境変数が既に設定されているはずです:

  • ACCESS_TOKEN
  • REALM
    • これらはワークショップ用の Splunk Observability Cloud の Access TokenRealm です。
    • これらは OpenTelemetry Collector によって、データを正しい Splunk Observability Cloud 組織に転送するために使用されます。

また、Multipass を使用してローカルの Observability ワークショップインスタンスをデプロイすることもできます。

AWS Command Line Interface (awscli)

AWS Command Line Interface、またはawscliは、AWS リソースと対話するために使用される API です。このワークショップでは、特定のスクリプトがデプロイするリソースと対話するために使用されます。

Splunk が提供するワークショップインスタンスには、既に awscli がインストールされているはずです。

  • インスタンスに aws コマンドがインストールされているか、次のコマンドで確認します:

    which aws
    • 予想される出力は /usr/local/bin/aws です
  • インスタンスに aws コマンドがインストールされていない場合は、次のコマンドを実行します:

    sudo apt install awscli

Terraform

Terraform は、リソースを構成ファイルで定義することで、デプロイ、管理、破棄するための Infrastructure as Code(IaC)プラットフォームです。Terraform は HCL を使用してこれらのリソースを定義し、さまざまなプラットフォームやテクノロジのための複数のプロバイダーをサポートしています。

このワークショップでは、コマンドラインで Terraform を使用して、以下のリソースをデプロイします:

  1. AWS API Gateway
  2. Lambda 関数
  3. Kinesis Stream
  4. CloudWatch ロググループ
  5. S3 バケット
    • およびその他のサポートリソース

Splunk が提供するワークショップインスタンスには、既に terraform がインストールされているはずです。

  • インスタンスに terraform コマンドがインストールされているか確認します:

    which terraform
    • 予想される出力は /usr/local/bin/terraform です
  • インスタンスに terraform コマンドがインストールされていない場合は、以下の Terraform が推奨するインストールコマンドを実行してください:

    wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    
    echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    
    sudo apt update && sudo apt install terraform

ワークショップディレクトリ (o11y-lambda-workshop)

ワークショップディレクトリ o11y-lambda-workshop は、今日使用する例の Lambda ベースのアプリケーションの自動計装と手動計装の両方を完了するための、すべての設定ファイルとスクリプトを含むリポジトリです。

  • ホームディレクトリにワークショップディレクトリがあることを確認します:

    cd && ls
    • 予想される出力には o11y-lambda-workshop が含まれるはずです
  • o11y-lambda-workshop ディレクトリがホームディレクトリにない場合は、次のコマンドでクローンします:

git clone https://github.com/gkono-splunk/o11y-lambda-workshop.git

AWS & Terraform 変数

AWS

AWS の CLI では、サービスによってデプロイされたリソースにアクセスし管理するための認証情報が必要です。このワークショップでは、Terraform と Python スクリプトの両方がタスクを実行するためにこれらの変数を必要とします。

  • このワークショップのために awscliaccess key IDsecret access key および region で構成します:

    aws configure
    • このコマンドは以下のようなプロンプトを表示するはずです:

      AWS Access Key ID [None]: XXXXXXXXXXXXXXXX
      AWS Secret Acces Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      Default region name [None]: us-east-1
      Default outoput format [None]:
  • インスタンスで awscli が設定されていない場合は、次のコマンドを実行し、インストラクターから提供される値を入力してください。

    aws configure

Terraform

Terraform では、機密情報や動的データを.tf 設定ファイルにハードコーディングさせない、またはそれらの値をリソース定義全体で再利用できるようにするため、変数の受け渡しをサポートしています。

このワークショップでは、OpenTelemetry Lambda layer の適切な値で Lambda 関数をデプロイするため、Splunk Observability Cloud の取り込み値のため、そして環境とリソースを独自で即座に認識できるようにするための変数を Terraform で必要とします。

Terraform 変数(variable)は以下の方法で定義されます:

  • 変数を main.tf ファイルまたは variables.tf に定義する
  • 以下のいずれかの方法で変数の値を設定する:
    • ホストレベルで環境変数を設定し、その定義と同じ変数名を使用して、接頭辞として TF_VAR をつける
    • terraform.tfvars ファイルに変数の値を設定する
    • terraform apply 実行時に引数として値を渡す

このワークショップでは、variables.tfterraform.tfvars ファイルの組み合わせを使用して変数を設定します。

  • vi または nano のいずれかを使用して、auto または manual ディレクトリにある terraform.tfvars ファイルを開きます

    vi ~/o11y-lambda-workshop/auto/terraform.tfvars
  • 変数に値を設定します。CHANGEME プレースホルダーをインストラクターから提供された値に置き換えてください。

    o11y_access_token = "CHANGEME"
    o11y_realm        = "CHANGEME"
    otel_lambda_layer = ["CHANGEME"]
    prefix            = "CHANGEME"
    • 引用符(")や括弧 ( [ ] ) はそのまま残し、プレースホルダーCHANGEMEのみを変更してください。
    • prefix は、他の参加者のリソースと区別するため、任意の文字列で設定する固有の識別子です。氏名やメールアドレスのエイリアスを使用することをお勧めします。
    • prefix には小文字のみを使用してください。S3 のような特定の AWS リソースでは、大文字を使用するとエラーが発生します。
  • ファイルを保存してエディタを終了します。

  • 最後に、編集した terraform.tfvars ファイルを他のディレクトリにコピーします。

    cp ~/o11y-lambda-workshop/auto/terraform.tfvars ~/o11y-lambda-workshop/manual
    • これは、自動計装と手動計装の両方の部分で同じ値を使用するためです

ファイル権限

他のすべてのファイルはそのままでよいですが、automanualの両方にあるsend_message.pyスクリプトは、ワークショップの一部として実行する必要があります。そのため、期待通りに実行するには、適切な権限が必要です。以下の手順に従って設定してください。

  • まず、o11y-lambda-workshopディレクトリにいることを確認します:

    cd ~/o11y-lambda-workshop
  • 次に、以下のコマンドを実行してsend_message.pyスクリプトに実行権限を設定します:

    sudo chmod 755 auto/send_message.py manual/send_message.py

これで前提条件が整いましたので、ワークショップを始めることができます!

Last Modified 2025/05/29

自動計装

ワークショップの最初の部分では、OpenTelemetry による自動計装がどのようにして OpenTelemetry Collector に関数がどの言語で書かれているかを自動検出させ、それらの関数のトレースの取得を開始させるかを示します。

自動計装ワークショップディレクトリとコンテンツ

まず、o11y-lambda-workshop/autoディレクトリとそのファイルの一部を見てみましょう。ここにはワークショップの自動計装部分のすべてのコンテンツがあります。

auto ディレクトリ

  • 以下のコマンドを実行して o11y-lambda-workshop/auto ディレクトリに移動します:

    cd ~/o11y-lambda-workshop/auto
  • このディレクトリの内容を確認します:

    ls
    • 出力には以下のファイルとディレクトリが含まれるはずです:

      handler             outputs.tf          terraform.tf        variables.tf
      main.tf             send_message.py     terraform.tfvars
    • 出力には以下のファイルとディレクトリが含まれるはずです:

      get_logs.py    main.tf       send_message.py
      handler        outputs.tf    terraform.tf

main.tf ファイル

  • main.tf ファイルをより詳しく見てみましょう:

    cat main.tf
ワークショップの質問
  • このテンプレートによってどの AWS リソースが作成されているか特定できますか?
  • OpenTelemetry 計装がどこでセットアップされているか特定できますか?
    • ヒント: Lambda 関数の定義を調べてください
  • 以前に設定した環境変数によってどの計装情報が提供されているか判断できますか?

各 Lambda 関数の環境変数が設定されているセクションが見つかるはずです。

environment {
  variables = {
    SPLUNK_ACCESS_TOKEN = var.o11y_access_token
    SPLUNK_REALM = var.o11y_realm
    OTEL_SERVICE_NAME = "producer-lambda"
    OTEL_RESOURCE_ATTRIBUTES = "deployment.environment=${var.prefix}-lambda-shop"
    AWS_LAMBDA_EXEC_WRAPPER = "/opt/nodejs-otel-handler"
    KINESIS_STREAM = aws_kinesis_stream.lambda_streamer.name
  }
}

これらの環境変数を使用することで、いくつかの方法で自動計装を構成しています:

  • 環境変数を設定して、データのエクスポート先となる Splunk Observability Cloud 組織を OpenTelemetry collector に伝えています。

    SPLUNK_ACCESS_TOKEN = var.o11y_access_token
    SPLUNK_ACCESS_TOKEN = var.o11y_realm
  • また、OpenTelemetry が関数/サービスを識別し、それが属する環境/アプリケーションを認識するのに役立つ変数も設定しています。

    OTEL_SERVICE_NAME = "producer-lambda" # consumer関数の場合はconsumer-lambda
    OTEL_RESOURCE_ATTRIBUTES = "deployment.environment=${var.prefix}-lambda-shop"
  • コード言語に基づいて、関数のハンドラーに自動的にトレースデータを取得するために適用する必要があるラッパーを OpenTelemetry に知らせる環境変数を設定しています。

    AWS_LAMBDA_EXEC_WRAPPER - "/opt/nodejs-otel-handler"
  • producer-lambda関数の場合、レコードを配置する Kinesis ストリームを関数に知らせるための環境変数を設定しています。

    KINESIS_STREAM = aws_kinesis_stream.lambda_streamer.name
  • これらの値は、「前提条件」セクションで設定した環境変数、および、この Terraform 構成ファイルの一部としてデプロイされるリソースから取得されます。

また、各関数に Splunk OpenTelemetry Lambda layer を設定する引数も確認できるはずです

layers = var.otel_lambda_layer
  • OpenTelemetry Lambda layer は、Lambda 関数の呼び出し時に計測データを収集、処理、およびエクスポートするために必要なライブラリと依存関係を含むパッケージです。

  • すべての OpenTelemetry サポート言語のライブラリと依存関係を持つ一般的な OTel Lambda layer がありますが、関数をさらに軽量化するための言語固有の Lambda layer も存在します。

    • 各 AWS リージョンの関連する Splunk OpenTelemetry Lambda layer ARN(Amazon Resource Name)と最新バージョンはこちらで確認できます

producer.mjs ファイル

次に、producer-lambda関数のコードを見てみましょう:

  • 以下のコマンドを実行してproducer.mjsファイルの内容を表示します:

    cat ~/o11y-lambda-workshop/auto/handler/producer.mjs
    • この NodeJS モジュールにはプロデューサー関数のコードが含まれています。
    • 基本的に、この関数はメッセージを受け取り、そのメッセージを対象の Kinesis ストリームにレコードとして配置します

Lambda 関数のデプロイとトレースデータの生成

autoディレクトリの内容に慣れたところで、ワークショップ用のリソースをデプロイし、Lambda 関数からトレースデータを生成していきます。

autoディレクトリで Terraform を初期化する

main.tfファイルで定義されたリソースをデプロイするには、まず Terraform がそのファイルと同じフォルダで初期化されていることを確認する必要があります。

  • auto ディレクトリにいることを確認します:

    pwd
    • 予想される出力は ~/o11y-lambda-workshop/auto です
  • auto ディレクトリにいない場合は、次のコマンドを実行します:

    cd ~/o11y-lambda-workshop/auto
  • 次のコマンドを実行して、このディレクトリで Terraform を初期化します

    terraform init
    • このコマンドは同じフォルダにいくつかの要素を作成します:
      • .terraform.lock.hcl ファイル:リソースを提供するために使用するプロバイダーを記録します
      • .terraform ディレクトリ:プロバイダーの構成を保存します
    • 上記のファイルに加えて、apply サブコマンドを使用して terraform を実行すると、デプロイされたリソースの状態を追跡するために terraform.tfstate ファイルが作成されます。
    • これらにより、Terraform は auto ディレクトリの main.tf ファイル内で定義されたとおりに、リソースの作成、状態、破棄を管理できます

Lambda 関数とその他の AWS リソースをデプロイする

このディレクトリで Terraform を初期化したら、リソースのデプロイに進むことができます。

  • まず、terraform plan コマンドを実行して、Terraform が問題なくリソースを作成できることを確認します。

    terraform plan
    • これにより、リソースをデプロイするプランといくつかのデータが出力され、意図したとおりに動作することを確認できます。
    • プランに表示される値の一部は、作成後に判明するか、セキュリティ上の理由でマスクされていることに注意してください。
  • 次に、terraform apply コマンドを実行して、main.tf ファイルから Lambda 関数とその他のサポートリソースをデプロイします:

    terraform apply
    • Enter a value: プロンプトが表示されたら yes と応答します

    • これにより、以下のような出力が得られます:

      Outputs:
      
      base_url = "https://______.amazonaws.com/serverless_stage/producer"
      consumer_function_name = "_____-consumer"
      consumer_log_group_arn = "arn:aws:logs:us-east-1:############:log-group:/aws/lambda/______-consumer"
      consumer_log_group_name = "/aws/lambda/______-consumer"
      environment = "______-lambda-shop"
      lambda_bucket_name = "lambda-shop-______-______"
      producer_function_name = "______-producer"
      producer_log_group_arn = "arn:aws:logs:us-east-1:############:log-group:/aws/lambda/______-producer"
      producer_log_group_name = "/aws/lambda/______-producer"
      • Terraform 出力は outputs.tf ファイルで定義されています。
      • これらの出力は、ワークショップの他の部分でもプログラム的に使用されます。

producer-lambda URL (base_url) にトラフィックを送信する

デプロイした Lambda 関数からトレースを取得し始めるには、トラフィックを生成する必要があります。producer-lambda関数のエンドポイントにメッセージを送信し、それを Kinesis ストリームにレコードとして配置し、その後consumer-lambda関数によってストリームから取得されるようにします。

  • auto ディレクトリにいることを確認します:

    pwd
    • 予想される出力は ~/o11y-lambda-workshop/auto です
  • auto ディレクトリにいない場合は、次のコマンドを実行します

    cd ~/o11y-lambda-workshop/auto

send_message.py スクリプトは、コマンドラインで入力を受け取り、JSON ディクショナリに追加し、while ループの一部として producer-lambda 関数のエンドポイントに繰り返し送信する Python スクリプトです。

  • Run the send_message.py script as a background process

    • --name--superpower 引数が必要です
    nohup ./send_message.py --name CHANGEME --superpower CHANGEME &
    • メッセージが成功した場合は、以下のような出力が表示されるはずです

      [1] 79829
      user@host manual % appending output to nohup.out
      • ここで重要な情報は 2 つあります:
        • 1 行目のプロセス ID(この例では 79829)、および
        • appending output to nohup.out メッセージ
      • nohup コマンドはスクリプトがバックグラウンドに送られた時に切断されないようにします。また、コマンドからの curl 出力を、現在いるフォルダと同じフォルダにある nohup.out ファイルにキャプチャします。
      • & はシェルプロセスにこのプロセスをバックグラウンドで実行するよう指示し、シェルが他のコマンドを実行できるようにします。
  • 次に、response.logs ファイルの内容を確認して、producer-lambda エンドポイントへのリクエストが成功したことを確認します:

    cat response.logs
    • メッセージが成功していれば、画面に印刷された行の中に次の出力が表示されるはずです:
    {"message": "Message placed in the Event Stream: {prefix}-lambda_stream"}
    • 失敗した場合は、次のように表示されます:
    {"message": "Internal server error"}
重要

この場合は、ワークショップ進行役の一人に支援を求めてください。

Lambda 関数のログを表示する

次に、Lambda 関数のログを確認しましょう。

  • producer-lambda ログを表示するには、producer.logs ファイルを確認します:

    cat producer.logs
  • consumer-lambda ログを表示するには、consumer.logs ファイルを確認します:

    cat consumer.logs

ログを注意深く調べてください。

ワークショップの質問
  • OpenTelemetry が読み込まれているのが見えますか?splunk-extension-wrapperのある行に注目してください
      • splunk-extension-wrapperが読み込まれているのを見るためにhead -n 50 producer.logsまたはhead -n 50 consumer.logsの実行を検討してください。
Last Modified 2025/05/29

Splunk APM、Lambda関数およびトレース

Lambda 関数は相当量のトレースデータを生成しているはずで、それを確認する必要があります。Lambda 関数のリソース定義で構成された環境変数と OpenTelemetry Lambda layer の組み合わせにより、Splunk APM で関数とトレースを表示する準備が整いました。

Splunk APM 概要で環境名を確認する

まず、Splunk APM が受信しているトレースデータからEnvironmentを認識していることを確認しましょう。これはmain.tfの Lambda 関数定義で設定したOTEL_RESOURCE_ATTRIBUTES変数の一部として設定したdeployment.nameです。これは先ほど実行したterraform applyコマンドの出力の 1 つでもありました。

Splunk Observability Cloud で:

  • 左側のメインメニューからAPMボタンをクリックします。これにより Splunk APM 概要に移動します。

  • Environment:ドロップダウンからあなたの APM 環境を選択します。

    • APM 環境はPREFIX-lambda-shop形式になっているはずです。PREFIXは前提条件セクションで設定した環境変数から取得されます
メモ

トレースが Splunk APM に表示されるまで数分かかる場合があります。環境のリストにあなたの環境名が表示されるまで、ブラウザの更新ボタンを押してみてください

Splunk APM, Environment Name Splunk APM, Environment Name

環境のサービスマップを表示する

Environment ドロップダウンから環境名を選択したら、Lambda 関数のサービスマップを確認できます。

  • APM 概要ページの右側にあるService Mapボタンをクリックします。これによりサービスマップビューに移動します。

Splunk APM、サービスマップボタン Splunk APM、サービスマップボタン

producer-lambda関数とそのレコードを配置するために Kinesis ストリームに対して行っている呼び出しが表示されるはずです。

Splunk APM、サービスマップ Splunk APM、サービスマップ

ワークショップの質問

あなたのconsumer-lambda関数はどうなっていますか?

Lambda 関数からのトレースを調査する

  • Tracesボタンをクリックしてトレースアナライザーを表示します。

Splunk APM、トレースボタン Splunk APM、トレースボタン

このページでは、producer-lambda関数の OpenTelemetry Lambda layer から取り込まれたトレースを確認できます。

Splunk APM、トレースアナライザー Splunk APM、トレースアナライザー

  • リストからハイパーリンクされたTrace IDをクリックして、調査するトレースを選択します。

Splunk APM、トレースとスパン Splunk APM、トレースとスパン

producer-lambda関数が Kinesis ストリームにレコードを配置しているのが確認できます。しかし、consumer-lambda関数のアクションが見当たりません!

これはトレースコンテキストが伝播されていないためです。このワークショップの時点では、Kinesis サービスはトレースコンテキスト伝播をすぐには対応していません。分散トレースは Kinesis サービスで止まっており、そのコンテキストがストリームを通じて自動的に伝播されないため、それ以上先を見ることができません。

少なくとも、今はまだ…

次のセクションでこの問題にどう対処するか見ていきましょう。しかしその前に、後片付けをしましょう!

クリーンアップ

この自動計装演習の一部としてデプロイしたリソースはクリーンアップする必要があります。同様に、producer-lambdaエンドポイントに対してトラフィックを生成していたスクリプトも、まだ実行中であれば停止する必要があります。以下の手順に従ってクリーンアップを行ってください。

send_messageの停止

  • send_message.pyスクリプトがまだ実行中の場合は、次のコマンドで停止します:

    fg
    • これによりバックグラウンドプロセスがフォアグラウンドに移動します。
    • 次に[CONTROL-C]を押してプロセスを終了できます。

全ての AWS リソースを破棄する

Terraform は個々のリソースの状態をデプロイメントとして管理するのに優れています。定義に変更があっても、デプロイされたリソースを更新することもできます。しかし、一からやり直すために、リソースを破棄し、このワークショップの手動計装部分の一部として再デプロイします。

以下の手順に従ってリソースを破棄してください:

  • autoディレクトリにいることを確認します:

    pwd
    • 期待される出力は ~/o11y-lambda-workshop/auto です
  • autoディレクトリにいない場合は、以下のコマンドを実行します:

    cd ~/o11y-lambda-workshop/auto
  • 先ほどデプロイした Lambda 関数とその他の AWS リソースを破棄します:

    terraform destroy
    • Enter a value:プロンプトが表示されたらyesと応答します
    • これによりリソースが破棄され、クリーンな環境が残ります

このプロセスにより、私たちの活動の結果として作成されたファイルとディレクトリは残ります。それらについては心配する必要はありません。

Last Modified 2025/05/29

手動計装

ワークショップの第 2 部では、OpenTelemetry による手動計装が計測データ収集を強化する方法を実演することに焦点を当てます。より具体的には、今回のケースでは、producer-lambda関数からconsumer-lambda関数にトレースコンテキストデータを伝播させることができるようになります。これにより、現在は自動コンテキスト伝播をサポートしていない Kinesis ストリームを介しても、2 つの関数間の関係を見ることができるようになります。

手動計装ワークショップディレクトリとコンテンツ

再度、作業ディレクトリとそのファイルの一部を確認することから始めます。今回は o11y-lambda-workshop/manual ディレクトリです。ここにはワークショップの手動計装部分のすべてのコンテンツがあります。

manual ディレクトリ

  • 以下のコマンドを実行して o11y-lambda-workshop/manual ディレクトリに移動します:

    cd ~/o11y-lambda-workshop/manual
  • ls コマンドでこのディレクトリの内容を確認します:

    ls
    • 出力には以下のファイルとディレクトリが含まれるはずです:

      handler             outputs.tf          terraform.tf        variables.tf
      main.tf             send_message.py     terraform.tfvars
ワークショップの質問

このディレクトリと最初に始めた auto ディレクトリに何か違いがありますか?

automanual のファイルを比較する

見た目が同じように見えるこれらのファイルが実際に同じかどうか確認しましょう。

  • automanual ディレクトリの main.tf ファイルを比較します:

    diff ~/o11y-lambda-workshop/auto/main.tf ~/o11y-lambda-workshop/manual/main.tf
    • 違いはありません!(違いがあるはずはありません。もし違いがあれば、ワークショップ進行役に支援を求めてください)
  • 次に、producer.mjs ファイルを比較してみましょう:

    diff ~/o11y-lambda-workshop/auto/handler/producer.mjs ~/o11y-lambda-workshop/manual/handler/producer.mjs
    • ここにはかなりの違いがあります!
  • ファイル全体を表示してその内容を調べたい場合は以下を実行します:

    cat ~/o11y-lambda-workshop/handler/producer.mjs
    • 必要な手動計装タスクを処理するために、いくつかの OpenTelemetry オブジェクトを関数に直接インポートしていることに注目してください。
    import { context, propagation, trace } from "@opentelemetry/api";
    • プロデューサー関数でコンテキストを伝播するために、@opentelemetry/api から次のオブジェクトをインポートしています:
      • context
      • propagation
      • trace
  • 最後に、consumer.mjs ファイルを比較します:

    diff ~/o11y-lambda-workshop/auto/handler/consumer.mjs ~/o11y-lambda-workshop/manual/handler/consumer.mjs
    • ここにもいくつかの注目すべき違いがあります。より詳しく見てみましょう:

      cat handler/consumer.mjs
      • このファイルでは、次の @opentelemetry/api オブジェクトをインポートしています:
        • propagation
        • trace
        • ROOT_CONTEXT
      • これらを使用して、プロデューサー関数から伝播されたトレースコンテキストを抽出します
      • その後、抽出したトレースコンテキストに namesuperpower に基づいた新しいスパン属性を追加します

プロデューサー関数からのトレースコンテキスト伝播

以下のコードはプロデューサー関数内で次のステップを実行します:

  1. このトレース用のトレーサーを取得する
  2. コンテキストキャリアオブジェクトを初期化する
  3. アクティブスパンのコンテキストをキャリアオブジェクトに注入する
  4. Kinesis ストリームに配置しようとしているレコードを修正し、アクティブスパンのコンテキストをコンシューマーに運ぶキャリアを含める
...
import { context, propagation, trace, } from "@opentelemetry/api";
...
const tracer = trace.getTracer('lambda-app');
...
  return tracer.startActiveSpan('put-record', async(span) => {
    let carrier = {};
    propagation.inject(context.active(), carrier);
    const eventBody = Buffer.from(event.body, 'base64').toString();
    const data = "{\"tracecontext\": " + JSON.stringify(carrier) + ", \"record\": " + eventBody + "}";
    console.log(
      `Record with Trace Context added:
      ${data}`
    );

    try {
      await kinesis.send(
        new PutRecordCommand({
          StreamName: streamName,
          PartitionKey: "1234",
          Data: data,
        }),
        message = `Message placed in the Event Stream: ${streamName}`
      )
...
    span.end();

コンシューマー関数でのトレースコンテキスト抽出

以下のコードはコンシューマー関数内で次のステップを実行します:

  1. producer-lambdaから取得したコンテキストをキャリアオブジェクトに抽出する
  2. 現在のコンテキストからトレーサーを抽出する
  3. 抽出したコンテキスト内でトレーサーを使用して新しいスパンを開始する
  4. ボーナス:メッセージからの値を含むカスタム属性など、追加の属性をスパンに追加する!
  5. 完了したら、スパンを終了する
import { propagation, trace, ROOT_CONTEXT } from "@opentelemetry/api";
...
      const carrier = JSON.parse( message ).tracecontext;
      const parentContext = propagation.extract(ROOT_CONTEXT, carrier);
      const tracer = trace.getTracer(process.env.OTEL_SERVICE_NAME);
      const span = tracer.startSpan("Kinesis.getRecord", undefined, parentContext);

      span.setAttribute("span.kind", "server");
      const body = JSON.parse( message ).record;
      if (body.name) {
        span.setAttribute("custom.tag.name", body.name);
      }
      if (body.superpower) {
        span.setAttribute("custom.tag.superpower", body.superpower);
      }
...
      span.end();

これでどのような違いが生まれるか見てみましょう!

Last Modified 2025/05/13

Lambda関数のデプロイとトレースデータの生成

トレースデータを収集したい関数やサービスに手動計装を適用する方法がわかったので、Lambda 関数を再度デプロイして、producer-lambdaエンドポイントに対するトラフィックを生成していきましょう。

manual ディレクトリで Terraform を初期化する

新しいディレクトリにいるので、ここでもう一度 Terraform を初期化する必要があります。

  • manual ディレクトリにいることを確認します:

    pwd
    • 予想される出力は ~/o11y-lambda-workshop/manual です
  • manual ディレクトリにいない場合は、次のコマンドを実行します:

    cd ~/o11y-lambda-workshop/manual
  • 次のコマンドを実行して、このディレクトリで Terraform を初期化します:

    terraform init

Lambda 関数とその他の AWS リソースをデプロイする

それでは、これらのリソースを再度デプロイしましょう!

  • 問題がないことを確認するために、terraform plan コマンドを実行します。

    terraform plan
  • 続いて、terraform apply コマンドを使用して main.tf ファイルから Lambda 関数とその他のサポートリソースをデプロイします:

    terraform apply
    • Enter a value: プロンプトが表示されたら yes と応答します

    • これにより、以下のような出力が得られます:

      Outputs:
      
      base_url = "https://______.amazonaws.com/serverless_stage/producer"
      consumer_function_name = "_____-consumer"
      consumer_log_group_arn = "arn:aws:logs:us-east-1:############:log-group:/aws/lambda/______-consumer"
      consumer_log_group_name = "/aws/lambda/______-consumer"
      environment = "______-lambda-shop"
      lambda_bucket_name = "lambda-shop-______-______"
      producer_function_name = "______-producer"
      producer_log_group_arn = "arn:aws:logs:us-east-1:############:log-group:/aws/lambda/______-producer"
      producer_log_group_name = "/aws/lambda/______-producer"

見ての通り、base_url の最初の部分とログループ ARN 以外は、このワークショップの自動計装部分をこの同じ時点まで実行したときと出力は概ね同じはずです。

producer-lambda エンドポイント (base_url) にトラフィックを送信する

もう一度、namesuperpower をメッセージとしてエンドポイントに送信します。これはトレースコンテキストとともに、Kinesis ストリーム内のレコードに追加されます。

  • manual ディレクトリにいることを確認します:

    pwd
    • 予想される出力は ~/o11y-lambda-workshop/manual です
  • manual ディレクトリにいない場合は、次のコマンドを実行します:

    cd ~/o11y-lambda-workshop/manual
  • send_message.py スクリプトをバックグラウンドプロセスとして実行します:

    nohup ./send_message.py --name CHANGEME --superpower CHANGEME &
  • 次に、response.logs ファイルの内容を確認して、producer-lambdaエンドポイントへの呼び出しが成功しているか確認します:

    cat response.logs
    • メッセージが成功していれば、画面に表示される行の中に次の出力が表示されるはずです:

      {"message": "Message placed in the Event Stream: hostname-eventStream"}
    • 失敗した場合は、次のように表示されます:

      {"message": "Internal server error"}
重要

これが発生した場合は、ワークショップ進行役の一人に支援を求めてください。

Lambda 関数のログの確認

ログがどのようになっているか見てみましょう。

  • producer.logs ファイルを確認します:

    cat producer.logs
  • そして consumer.logs ファイルを確認します:

    cat consumer.logs

ログを注意深く調べてください。

ワークショップの質問

違いに気づきましたか?

consumer-lambda ログからのトレース ID のコピー

今回は、consumer-lambda のロググループが、我々が伝播したtracecontextとともに、メッセージをrecordとしてログに記録しているのが確認できます。

トレース ID をコピーするには:

  • Kinesis Messageログの 1 つを見てみましょう。その中にはdataディクショナリがあります
  • ネストされたtracecontextディクショナリを見るために、dataをより詳しく見てください
  • tracecontextディクショナリ内には、traceparentというキーと値のペアがあります
  • traceparentキーと値のペアには、私たちが探しているトレース ID が含まれています
    • -で区切られた 4 つの値のグループがあります。トレース ID は 2 番目の文字グループです
  • トレース ID をコピーして保存してください。 このワークショップの後のステップで必要になります

Lambda Consumer Logs、手動計装 Lambda Consumer Logs、手動計装

Last Modified 2025/05/29

Splunk APM、Lambda関数とトレース、再び!

ログの外部でコンテキスト伝播の結果を確認するために、もう一度Splunk APM UIを参照します。

Splunk APM サービスマップで Lambda 関数を表示する

もう一度 APM で環境のサービスマップを確認してみましょう。

Splunk Observability Cloud で:

  • メインメニューのAPMボタンをクリックします。

  • Environment:ドロップダウンからあなたの APM 環境を選択します。

  • APM 概要ページの右側にあるService Mapボタンをクリックします。これによりサービスマップビューに移動します。

> 注意:トレースが Splunk APM に表示されるまで数分かかる場合があります。環境のリストにあなたの環境名が表示されるまで、ブラウザの更新ボタンを押してみてください
ワークショップの質問

違いに気づきましたか?

  • 今回は、伝播されたコンテキストによってリンクされたproducer-lambdaconsumer-lambda関数が見えるはずです!

Splunk APM、サービスマップ Splunk APM、サービスマップ

トレース ID で Lambda トレースを調査する

次に、環境に関連するトレースをもう一度確認します。

  • コンシューマー関数のログからコピーしたトレース ID を、Traces 下のView Trace ID検索ボックスに貼り付け、Goをクリックします

Splunk APM、トレースボタン Splunk APM、トレースボタン

メモ

トレース ID は、私たちが伝播したトレースコンテキストの一部でした。

最も一般的な 2 つの伝播規格について読むことができます:

  1. W3C
  2. B3
ワークショップの質問

私たちはどちらを使用していますか?

  • 私たちの NodeJS 関数をサポートする Splunk Distribution of Opentelemetry JS は、デフォルトW3C標準を使用しています
ワークショップの質問

ボーナス質問:W3C ヘッダーと B3 ヘッダーを混在させるとどうなりますか?

Splunk APM、IDによるトレース Splunk APM、IDによるトレース

consumer-lambdaスパンをクリックしてください。

ワークショップの質問

あなたのメッセージからの属性を見つけることができますか?

Splunk APM、スパンタグ Splunk APM、スパンタグ

クリーンアップ

いよいよワークショップの最後に来ました。後片付けをしましょう!

send_messageの停止

  • send_message.pyスクリプトがまだ実行中の場合は、次のコマンドで停止します:

    fg
    • これによりバックグラウンドプロセスがフォアグラウンドに移動します。
    • 次に[CONTROL-C]を押してプロセスを終了できます。

すべての AWS リソースを破棄する

Terraform は個々のリソースの状態をデプロイメントとして管理するのに優れています。定義に変更があっても、デプロイされたリソースを更新することもできます。しかし、一からやり直すために、リソースを破棄し、このワークショップの手動計装部分の一部として再デプロイします。

以下の手順に従ってリソースを破棄してください:

  • manualディレクトリにいることを確認します:

    pwd
    • 予想される出力は ~/o11y-lambda-workshop/manual です
  • manualディレクトリにいない場合は、次のコマンドを実行します:

    cd ~/o11y-lambda-workshop/manual
  • 以前にデプロイした Lambda 関数とその他の AWS リソースを破棄します:

    terraform destroy
    • Enter a value:プロンプトが表示されたらyesと応答します
    • これにより、リソースが破棄され、クリーンな環境が残ります
Last Modified 2025/05/13

結論

Lambda Tracing ワークショップを終えたことをおめでとうございます!自動計装を手動のステップで補完して、producer-lambda関数のコンテキストを Kinesis ストリーム内のレコードを介してconsumer-lambda関数に送信する方法を見てきました。これにより、期待される分散トレースを構築し、Splunk APM で両方の関数間の関係をコンテキスト化することができました。

完全に計装されたLambdaアプリケーション 完全に計装されたLambdaアプリケーション

これで、2 つの異なる関数を手動でリンクしてトレースを構築することができます。これは、自動計装や第三者のシステムがコンテキスト伝播を標準でサポートしていない場合や、より関連性の高いトレース分析のためにカスタム属性をトレースに追加したい場合に役立ちます。

Last Modified 2025/05/13

OpenTelemetry、Docker、K8sを実践で学ぶ

2 minutes   Author Derek Mitchell

このワークショップでは、以下の項目について実践経験を積むことができます:

  • Linux および Kubernetes 環境で、Splunk ディストリビューションの OpenTelemetry .NET を使用してコレクターのデプロイと.NET アプリケーションの計装を実践します。
  • .NET アプリケーションの「Docker 化」、Docker での実行、そして Splunk OpenTelemetry 計装の追加を実践します。
  • Helm を使用した K8s 環境での Splunk ディストロのコレクターのデプロイを実践します。その後、コレクター設定をカスタマイズし、問題のトラブルシューティングを行います。
Tip

このワークショップを最も簡単にナビゲートする方法は以下を使用することです:

  • このページの右上にある左右の矢印(< | >
  • キーボードの左(◀️)と右(▶️)のカーソルキー
Last Modified 2025/06/17

OpenTelemetry、Docker、K8sを実践で学ぶのサブセクション

EC2インスタンスへの接続

5 minutes  

EC2 インスタンスへ接続

各参加者のために、AWS/EC2 に Ubuntu Linux インスタンスを用意しました。

インストラクターから提供された IP アドレスとパスワードを使用して、以下のいずれかの方法で EC2 インスタンスに接続してください:

  • Mac OS / Linux
    • ssh splunk@IP アドレス
  • Windows 10+
    • OpenSSH クライアントを使用
  • 以前のバージョンの Windows
    • Putty を使用
Last Modified 2025/06/16

OpenTelemetryコレクターのデプロイ

10 minutes  

OpenTelemetry コレクターのアンインストール

EC2 インスタンスには、すでに Splunk Distribution の OpenTelemetry コレクターの古いバージョンが インストールされている可能性があります。先に進む前に、次のコマンドを使用してアンインストールしましょう:

curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh;
sudo sh /tmp/splunk-otel-collector.sh --uninstall
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  splunk-otel-collector*
0 upgraded, 0 newly installed, 1 to remove and 167 not upgraded.
After this operation, 766 MB disk space will be freed.
(Reading database ... 157441 files and directories currently installed.)
Removing splunk-otel-collector (0.92.0) ...
(Reading database ... 147373 files and directories currently installed.)
Purging configuration files for splunk-otel-collector (0.92.0) ...
Scanning processes...
Scanning candidates...
Scanning linux images...

Running kernel seems to be up-to-date.

Restarting services...
 systemctl restart fail2ban.service falcon-sensor.service
Service restarts being deferred:
 systemctl restart networkd-dispatcher.service
 systemctl restart unattended-upgrades.service

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.
Successfully removed the splunk-otel-collector package

OpenTelemetry collector のデプロイ

Linux EC2 インスタンスに、Splunk Distribution の OpenTelemetry コレクターの最新バージョンをデプロイしましょう。

これはcurlを使用してコレクターバイナリをダウンロードし、特定の引数を指定して実行することで可能です。 これらの引数は、データを送信する realm、使用するアクセストークン、 およびデータを送信するデプロイメント環境をコレクターに指示します。

Splunk Observability Cloud におけるデプロイメント環境とは、システムまたはアプリケーションの個別のデプロイメントであり、同じアプリケーションの他のデプロイメントの設定と重複しない設定を行うことができます。

curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh; \
sudo sh /tmp/splunk-otel-collector.sh \
--realm $REALM \
--mode agent \
--without-instrumentation \
--deployment-environment otel-$INSTANCE \
-- $ACCESS_TOKEN
Splunk OpenTelemetry Collector Version: latest
Memory Size in MIB: 512
Realm: us1
Ingest Endpoint: https://ingest.us1.signalfx.com
API Endpoint: https://api.us1.signalfx.com
HEC Endpoint: https://ingest.us1.signalfx.com/v1/log
etc.

詳細については、インストーラースクリプトを使用した Linux 用コレクターのインストール を参照してください。

コレクターが実行中であることを確認

インスタンスでコレクターが正常に実行されていることを確認しましょう。

ステータスコマンドを終了するには、Ctrl + C を押します。

sudo systemctl status splunk-otel-collector
● splunk-otel-collector.service - Splunk OpenTelemetry Collector
     Loaded: loaded (/lib/systemd/system/splunk-otel-collector.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/splunk-otel-collector.service.d
             └─service-owner.conf
     Active: active (running) since Fri 2024-12-20 00:13:14 UTC; 45s ago
   Main PID: 14465 (otelcol)
      Tasks: 9 (limit: 19170)
     Memory: 117.4M
        CPU: 681ms
     CGroup: /system.slice/splunk-otel-collector.service
             └─14465 /usr/bin/otelcol

コレクターログの確認方法

journalctlを使用してコレクターログを表示できます:

ログの監視を終了するには、Ctrl + C を押します。

sudo journalctl -u splunk-otel-collector -f -n 100
Dec 20 00:13:14 derek-1 systemd[1]: Started Splunk OpenTelemetry Collector.
Dec 20 00:13:14 derek-1 otelcol[14465]: 2024/12/20 00:13:14 settings.go:483: Set config to /etc/otel/collector/agent_config.yaml
Dec 20 00:13:14 derek-1 otelcol[14465]: 2024/12/20 00:13:14 settings.go:539: Set memory limit to 460 MiB
Dec 20 00:13:14 derek-1 otelcol[14465]: 2024/12/20 00:13:14 settings.go:524: Set soft memory limit set to 460 MiB
Dec 20 00:13:14 derek-1 otelcol[14465]: 2024/12/20 00:13:14 settings.go:373: Set garbage collection target percentage (GOGC) to 400
Dec 20 00:13:14 derek-1 otelcol[14465]: 2024/12/20 00:13:14 settings.go:414: set "SPLUNK_LISTEN_INTERFACE" to "127.0.0.1"
etc.

コレクターの設定

このコレクターが使用している設定はどこで見つけられるでしょうか?

その設定は/etc/otel/collectorディレクトリにあります。コレクターをagentモードで インストールしたため、コレクター設定はagent_config.yamlファイルにあります。

Last Modified 2025/06/17

.NETアプリケーションのデプロイ

10 minutes  

前提条件

アプリケーションをデプロイする前に、インスタンスに.NET 8 SDK をインストールする必要があります。

sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-8.0
Hit:1 http://us-west-1.ec2.archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://us-west-1.ec2.archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:3 http://us-west-1.ec2.archive.ubuntu.com/ubuntu jammy-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu jammy-security InRelease
Ign:5 https://splunk.jfrog.io/splunk/otel-collector-deb release InRelease
Hit:6 https://splunk.jfrog.io/splunk/otel-collector-deb release Release
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  aspnetcore-runtime-8.0 aspnetcore-targeting-pack-8.0 dotnet-apphost-pack-8.0 dotnet-host-8.0 dotnet-hostfxr-8.0 dotnet-runtime-8.0 dotnet-targeting-pack-8.0 dotnet-templates-8.0 liblttng-ust-common1
  liblttng-ust-ctl5 liblttng-ust1 netstandard-targeting-pack-2.1-8.0
The following NEW packages will be installed:
  aspnetcore-runtime-8.0 aspnetcore-targeting-pack-8.0 dotnet-apphost-pack-8.0 dotnet-host-8.0 dotnet-hostfxr-8.0 dotnet-runtime-8.0 dotnet-sdk-8.0 dotnet-targeting-pack-8.0 dotnet-templates-8.0
  liblttng-ust-common1 liblttng-ust-ctl5 liblttng-ust1 netstandard-targeting-pack-2.1-8.0
0 upgraded, 13 newly installed, 0 to remove and 0 not upgraded.
Need to get 138 MB of archives.
After this operation, 495 MB of additional disk space will be used.
etc.

詳細については、Ubuntu に.NET SDK または.NET Runtime をインストールする を参照してください。

.NET アプリケーションの確認

ターミナルで、アプリケーションディレクトリに移動します:

cd ~/workshop/docker-k8s-otel/helloworld

このワークショップでは、シンプルな「Hello World」.NET アプリケーションを使用します。主要なロジックは HelloWorldController.cs ファイルにあります:

public class HelloWorldController : ControllerBase
{
    private ILogger<HelloWorldController> logger;

    public HelloWorldController(ILogger<HelloWorldController> logger)
    {
        this.logger = logger;
    }

    [HttpGet("/hello/{name?}")]
    public string Hello(string name)
    {
        if (string.IsNullOrEmpty(name))
        {
           logger.LogInformation("/hello endpoint invoked anonymously");
           return "Hello, World!";
        }
        else
        {
            logger.LogInformation("/hello endpoint invoked by {name}", name);
            return String.Format("Hello, {0}!", name);
        }
    }
}

.NET アプリケーションのビルドと実行

以下のコマンドを使用してアプリケーションをビルドできます:

dotnet build
MSBuild version 17.8.5+b5265ef37 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  helloworld -> /home/splunk/workshop/docker-k8s-otel/helloworld/bin/Debug/net8.0/helloworld.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.04

ビルドが成功したら、次のように実行できます:

dotnet run
Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:8080
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/splunk/workshop/docker-k8s-otel/helloworld

実行したら、Ubuntu インスタンスへの SSH 接続を 2 つ目のターミナルで開き、curl を使用してアプリケーションにアクセスします:

curl http://localhost:8080/hello
Hello, World!

名前を渡すこともできます:

curl http://localhost:8080/hello/Tom
Hello, Tom!

次のステップに進む前に、Ctrl + C を押して Helloworld アプリを終了してください。

次のステップ

アプリケーションを OpenTelemetry で計装するために使用できる 3 つの方法は何でしょうか?

Traces Traces

オプションの詳細については、Splunk Observability Cloud 用の.NET アプリケーションの計装 を参照してください。

Last Modified 2025/06/17

OpenTelemetryで.NETアプリケーションを計装する

20 minutes  

Splunk Distribution of OpenTelemetry のダウンロード

このワークショップでは、NuGet パッケージを使用せず、Splunk Distribution of OpenTelemetry を 手動でインストールします。

最新のsplunk-otel-dotnet-install.shファイルをダウンロードすることから始めます。 これを使用して.NET アプリケーションを計装します:

cd ~/workshop/docker-k8s-otel/helloworld

curl -sSfL https://github.com/signalfx/splunk-otel-dotnet/releases/latest/download/splunk-otel-dotnet-install.sh -O

インストールプロセスの詳細については、Splunk Distribution of OpenTelemetry .NET の手動インストール を参照してください。

ディストリビューションのインストール

ターミナルで、以下のようにディストリビューションをインストールします

sh ./splunk-otel-dotnet-install.sh
Downloading v1.8.0 for linux-glibc (/tmp/tmp.m3tSdtbmge/splunk-opentelemetry-dotnet-linux-glibc-x64.zip)...

注意:上記のコマンドを実行する際には、ARCHITECTURE 環境変数を含める必要がある場合があります:

ARCHITECTURE=x64 sh ./splunk-otel-dotnet-install.sh

計装の有効化

次に、OpenTelemetry 計装を有効化できます:

. $HOME/.splunk-otel-dotnet/instrument.sh

デプロイメント環境の設定

デプロイメント環境を設定して、データが Splunk Observability Cloud 内の独自の 環境に流れるようにしましょう:

export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=otel-$INSTANCE

計装を使用したアプリケーションの実行

以下のようにアプリケーションを実行できます:

dotnet run

チャレンジ

Linux インスタンスから C#アプリケーションによってエクスポートされているトレースをどのように確認できるでしょうか?

答えを見るにはここをクリック

これを行う方法は 2 つあります:

  1. dotnet runコマンドの開始時にOTEL_TRACES_EXPORTER=otlp,consoleを追加することで、トレースが OTLP 経由でコレクターに書き込まれるとともに、コンソールにも書き込まれるようになります。
OTEL_TRACES_EXPORTER=otlp,console dotnet run
  1. あるいは、コレクター設定にデバッグエクスポーターを追加し、それをトレースパイプラインに追加することで、トレースがコレクターログに書き込まれるようになります。
exporters:
  debug:
    verbosity: detailed
service:
  pipelines:
    traces:
      receivers: [jaeger, otlp, zipkin]
      processors:
        - memory_limiter
        - batch
        - resourcedetection
      exporters: [otlphttp, signalfx, debug]

アプリケーションへのアクセス

アプリケーションが実行中になったら、2 つ目の SSH ターミナルを使用して curl でアクセスします:

curl http://localhost:8080/hello

以前と同様に、Hello, World!が返されるはずです。

トレースログを有効にした場合は、以下のようなトレースがコンソールまたはコレクターログに書き込まれているのを確認できるはずです:

info: Program[0]
      /hello endpoint invoked anonymously
Activity.TraceId:            c7bbf57314e4856447508cd8addd49b0
Activity.SpanId:             1c92ac653c3ece27
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        GET /hello/{name?}
Activity.Kind:               Server
Activity.StartTime:          2024-12-20T00:45:25.6551267Z
Activity.Duration:           00:00:00.0006464
Activity.Tags:
    server.address: localhost
    server.port: 8080
    http.request.method: GET
    url.scheme: http
    url.path: /hello
    network.protocol.version: 1.1
    user_agent.original: curl/7.81.0
    http.route: /hello/{name?}
    http.response.status_code: 200
Resource associated with Activity:
    splunk.distro.version: 1.8.0
    telemetry.distro.name: splunk-otel-dotnet
    telemetry.distro.version: 1.8.0
    service.name: helloworld
    os.type: linux
    os.description: Ubuntu 22.04.5 LTS
    os.build_id: 6.8.0-1021-aws
    os.name: Ubuntu
    os.version: 22.04
    host.name: derek-1
    host.id: 20cf15fcc7054b468647b73b8f87c556
    process.owner: splunk
    process.pid: 16997
    process.runtime.description: .NET 8.0.11
    process.runtime.name: .NET
    process.runtime.version: 8.0.11
    container.id: 2
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.9.0
    deployment.environment: otel-derek-1

Splunk Observability Cloud でのアプリケーションの確認

セットアップが完了したので、トレースがSplunk Observability Cloudに送信されていることを確認しましょう。アプリケーションが初回デプロイされた場合、データが表示されるまでに数分かかる場合があることに注意してください。

APM にナビゲートし、Environment ドロップダウンを使用してあなたの環境(つまりotel-instancename)を選択します。

すべてが正しくデプロイされている場合、サービスのリストにhelloworldが表示されるはずです:

APM Overview APM Overview

右側のService Mapをクリックしてサービスマップを表示します。

Service Map Service Map

次に、右側のTracesをクリックして、このアプリケーションでキャプチャされたトレースを確認します。

Traces Traces

個別のトレースは以下のように表示されるはずです:

Traces Traces

次のステップに進む前に、Ctrl + C を押して Helloworld アプリを終了してください。

Last Modified 2025/06/17

アプリケーションのDocker化

15 minutes  

このワークショップの後半では、.NET アプリケーションを Kubernetes クラスターにデプロイします。

しかし、どのようにそれを行うのでしょうか?

最初のステップは、アプリケーション用の Docker イメージを作成することです。これは アプリケーションの「Docker 化」として知られており、プロセスはDockerfileの作成から始まります。

しかし、まず重要な用語を定義しましょう。

重要な用語

Docker とは何ですか?

「Docker は、コンテナと呼ばれる緩い分離環境でアプリケーションをパッケージ化して実行する機能を提供します。分離とセキュリティにより、指定されたホスト上で同時に多くのコンテナを実行できます。コンテナは軽量で、アプリケーションの実行に必要なすべてを含んでいるため、ホストにインストールされているものに依存する必要がありません。」

ソース: https://docs.docker.com/get-started/docker-overview/

コンテナとは何ですか?

「コンテナは、アプリのコンポーネントごとの分離されたプロセスです。各コンポーネントは…独自の分離された環境で実行され、マシン上の他のすべてのものから完全に分離されています。」

ソース: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/

コンテナイメージとは何ですか?

「コンテナイメージは、コンテナを実行するためのすべてのファイル、バイナリ、ライブラリ、および設定を含む標準化されたパッケージです。」

Dockerfile

「Dockerfile は、コンテナイメージを作成するために使用されるテキストベースのドキュメントです。実行するコマンド、コピーするファイル、起動コマンドなどに関するイメージビルダーへの指示を提供します。」

Dockerfile の作成

/home/splunk/workshop/docker-k8s-otel/helloworldディレクトリにDockerfileという名前のファイルを作成しましょう。

cd /home/splunk/workshop/docker-k8s-otel/helloworld

ファイルの作成には vi または nano を使用できます。vi を使用した例を示します:

vi Dockerfile

新しく開いたファイルに以下の内容をコピー&ペーストします:

以下のテキストを貼り付ける前に、vi で「i」を押して挿入モードに入ってください。

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["helloworld.csproj", "helloworld/"]
RUN dotnet restore "./helloworld/./helloworld.csproj"
WORKDIR "/src/helloworld"
COPY . .
RUN dotnet build "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

ENTRYPOINT ["dotnet", "helloworld.dll"]

vi での変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

これはすべて何を意味するのでしょうか?詳しく見てみましょう。

Dockerfile の詳細解説

この例では、マルチステージ Dockerfile を使用しており、Docker イメージ作成プロセスを以下のステージに分けています:

  • Base(ベース)
  • Build(ビルド)
  • Publish(パブリッシュ)
  • Final(最終)

マルチステージアプローチはより複雑ですが、デプロイメント用により 軽量なランタイムイメージを作成することができます。以下では、 これらの各ステージの目的を説明します。

ベースステージ

ベースステージでは、アプリを実行するユーザー、作業ディレクトリを定義し、 アプリにアクセスするために使用されるポートを公開します。 これは Microsoft のmcr.microsoft.com/dotnet/aspnet:8.0イメージをベースにしています:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080

なお、mcr.microsoft.com/dotnet/aspnet:8.0イメージには.NET runtime のみが含まれており、 SDK は含まれていないため、比較的軽量です。これは Debian 12 Linux distribution がベースになっています。ASP.NET Core Runtime Docker イメージの詳細については GitHubで確認できます。

Build ステージ

Dockerfile の次のステージは build ステージです。このステージでは、 mcr.microsoft.com/dotnet/sdk:8.0イメージが使用されます。これも Debian 12 がベースになっていますが、 runtime だけでなく完全な.NET SDKが含まれています。

このステージでは.csprojファイルを build イメージにコピーし、その後dotnet restoreを使用して アプリケーションが使用する依存関係をダウンロードします。

次に、アプリケーションコードを build イメージにコピーし、 dotnet buildを使用してプロジェクトとその依存関係を .dllバイナリのセットにビルドします:

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["helloworld.csproj", "helloworld/"]
RUN dotnet restore "./helloworld/./helloworld.csproj"
WORKDIR "/src/helloworld"
COPY . .
RUN dotnet build "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/build

Publish ステージ

3 番目のステージは publish で、これは Microsoft イメージではなく build ステージイメージをベースにしています。このステージでは、dotnet publishを使用して アプリケーションとその依存関係を deployment 用にパッケージ化します:

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

Final ステージ

4 番目のステージは最終ステージで、これは base ステージイメージをベースにしています(build と publish ステージよりも軽量)。publish ステージイメージからの出力をコピーし、 アプリケーションの entry point を定義します:

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

ENTRYPOINT ["dotnet", "helloworld.dll"]

Docker イメージのビルド

Dockerfileができたので、これを使用してアプリケーションを含む Docker イメージを ビルドできます:

docker build -t helloworld:1.0 .
DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
            Install the buildx component to build images with BuildKit:
            https://docs.docker.com/go/buildx/

Sending build context to Docker daemon  281.1kB
Step 1/19 : FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
8.0: Pulling from dotnet/aspnet
af302e5c37e9: Pull complete
91ab5e0aabf0: Pull complete
1c1e4530721e: Pull complete
1f39ca6dcc3a: Pull complete
ea20083aa801: Pull complete
64c242a4f561: Pull complete
Digest: sha256:587c1dd115e4d6707ff656d30ace5da9f49cec48e627a40bbe5d5b249adc3549
Status: Downloaded newer image for mcr.microsoft.com/dotnet/aspnet:8.0
 ---> 0ee5d7ddbc3b
Step 2/19 : USER app
etc,

これは、現在のディレクトリのDockerfileを使用してhelloworld:1.0のタグでイメージをビルドするよう Docker に指示します。

以下のコマンドで正常に作成されたことを確認できます:

docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
helloworld   1.0       db19077b9445   20 seconds ago   217MB

Docker イメージのテスト

続行する前に、以前に開始したアプリケーションがインスタンス上で実行されていないことを確認してください。

Docker イメージを使用して以下のようにアプリケーションを実行できます:

docker run --name helloworld \
--detach \
--expose 8080 \
--network=host \
helloworld:1.0

注意:--network=hostパラメータを含めて、Docker コンテナが インスタンス上のリソースにアクセスできるようにしています。これは後でアプリケーションが localhost 上で実行されているコレクターにデータを送信する必要がある場合に重要です。

Docker コンテナが実行されていることを確認しましょう:

docker ps
$ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED       STATUS       PORTS     NAMES
5f5b9cd56ac5   helloworld:1.0   "dotnet helloworld.d…"   2 mins ago    Up 2 mins              helloworld

以前と同様にアプリケーションにアクセスできます:

curl http://localhost:8080/hello/Docker
Hello, Docker!

おめでとうございます。ここまで到達したということは、.NET アプリケーションの Docker 化に成功したということです。

Last Modified 2025/06/17

Dockerfileに計装を追加する

10 minutes  

アプリケーションを正常に Docker 化したので、次に OpenTelemetry による計装 を追加しましょう。

これは、Linux で実行しているアプリケーションを計装した際の手順と似ていますが、 注意すべきいくつかの重要な違いがあります。

Dockerfile の更新

/home/splunk/workshop/docker-k8s-otel/helloworldディレクトリのDockerfileを更新しましょう。

Dockerfile で.NET アプリケーションがビルドされた後、以下の操作を行いたいと思います:

  • splunk-otel-dotnet-install.shをダウンロードして実行するために必要な依存関係を追加する
  • Splunk OTel .NET インストーラーをダウンロードする
  • ディストリビューションをインストールする

Dockerfile のビルドステージに以下を追加できます。vi で Dockerfile を開きましょう:

vi /home/splunk/workshop/docker-k8s-otel/helloworld/Dockerfile

vi では「i」キーを押して編集モードに入ります ‘NEW CODE’とマークされている行を Dockerfile のビルドステージセクションに貼り付けてください:

# CODE ALREADY IN YOUR DOCKERFILE:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["helloworld.csproj", "helloworld/"]
RUN dotnet restore "./helloworld/./helloworld.csproj"
WORKDIR "/src/helloworld"
COPY . .
RUN dotnet build "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/build

# NEW CODE: add dependencies for splunk-otel-dotnet-install.sh
RUN apt-get update && \
 apt-get install -y unzip

# NEW CODE: download Splunk OTel .NET installer
RUN curl -sSfL https://github.com/signalfx/splunk-otel-dotnet/releases/latest/download/splunk-otel-dotnet-install.sh -O

# NEW CODE: install the distribution
RUN sh ./splunk-otel-dotnet-install.sh

次に、以下の変更で Dockerfile の最終ステージを更新します:

  • ビルドイメージから最終イメージに/root/.splunk-otel-dotnet/をコピーする
  • entrypoint.sh ファイルもコピーする
  • OTEL_SERVICE_NAMEOTEL_RESOURCE_ATTRIBUTES環境変数を設定する
  • ENTRYPOINTentrypoint.shに設定する

最も簡単な方法は、最終ステージ全体を以下の内容で置き換えることです:

重要 Dockerfile の$INSTANCEをあなたのインスタンス名に置き換えてください。 インスタンス名はecho $INSTANCEを実行することで確認できます。

# CODE ALREADY IN YOUR DOCKERFILE
FROM base AS final

# NEW CODE: Copy instrumentation file tree
WORKDIR "//home/app/.splunk-otel-dotnet"
COPY --from=build /root/.splunk-otel-dotnet/ .

# CODE ALREADY IN YOUR DOCKERFILE
WORKDIR /app
COPY --from=publish /app/publish .

# NEW CODE: copy the entrypoint.sh script
COPY entrypoint.sh .

# NEW CODE: set OpenTelemetry environment variables
ENV OTEL_SERVICE_NAME=helloworld
ENV OTEL_RESOURCE_ATTRIBUTES='deployment.environment=otel-$INSTANCE'

# NEW CODE: replace the prior ENTRYPOINT command with the following two lines
ENTRYPOINT ["sh", "entrypoint.sh"]
CMD ["dotnet", "helloworld.dll"]

vi での変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

これらすべての変更の後、Dockerfile は以下のようになるはずです:

重要 このコンテンツを自分の Dockerfile にコピー&ペーストする場合は、 Dockerfile の$INSTANCEをあなたのインスタンス名に置き換えてください。 インスタンス名はecho $INSTANCEを実行することで確認できます。

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["helloworld.csproj", "helloworld/"]
RUN dotnet restore "./helloworld/./helloworld.csproj"
WORKDIR "/src/helloworld"
COPY . .
RUN dotnet build "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/build

# NEW CODE: add dependencies for splunk-otel-dotnet-install.sh
RUN apt-get update && \
 apt-get install -y unzip

# NEW CODE: download Splunk OTel .NET installer
RUN curl -sSfL https://github.com/signalfx/splunk-otel-dotnet/releases/latest/download/splunk-otel-dotnet-install.sh -O

# NEW CODE: install the distribution
RUN sh ./splunk-otel-dotnet-install.sh

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./helloworld.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final

# NEW CODE: Copy instrumentation file tree
WORKDIR "//home/app/.splunk-otel-dotnet"
COPY --from=build /root/.splunk-otel-dotnet/ .

WORKDIR /app
COPY --from=publish /app/publish .

# NEW CODE: copy the entrypoint.sh script
COPY entrypoint.sh .

# NEW CODE: set OpenTelemetry environment variables
ENV OTEL_SERVICE_NAME=helloworld
ENV OTEL_RESOURCE_ATTRIBUTES='deployment.environment=otel-$INSTANCE'

# NEW CODE: replace the prior ENTRYPOINT command with the following two lines
ENTRYPOINT ["sh", "entrypoint.sh"]
CMD ["dotnet", "helloworld.dll"]

entrypoint.sh ファイルの作成

また、/home/splunk/workshop/docker-k8s-otel/helloworldフォルダにentrypoint.shという名前のファイルを 以下の内容で作成する必要があります:

vi /home/splunk/workshop/docker-k8s-otel/helloworld/entrypoint.sh

次に、新しく作成したファイルに以下のコードを貼り付けます:

#!/bin/sh
# Read in the file of environment settings
. /$HOME/.splunk-otel-dotnet/instrument.sh

# Then run the CMD
exec "$@"

vi での変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

entrypoint.shスクリプトは、計装に含まれる instrument.sh スクリプトが環境変数をコンテナ起動時に取得するために必要です。これにより、各プラットフォームに対して環境変数が正しく設定されることが保証されます。

「なぜ Linux ホスト上で OpenTelemetry .NET instrumentation を有効化したときのように、 Dockerfile に以下のコマンドを含めるだけではだめなのか?」と疑問に思うかもしれません。

RUN . $HOME/.splunk-otel-dotnet/instrument.sh

この方法の問題点は、各 Dockerfile RUN ステップが新しいコンテナと新しいシェルで実行されることです。 あるシェルで環境変数を設定しようとしても、後で見ることはできません。 この問題は、ここで行ったようにエントリポイントスクリプトを使用することで解決されます。 この問題についての詳細は、こちらのStack Overflow の投稿を参照してください。

Docker イメージのビルド

OpenTelemetry .NET instrumentation を含む新しい Docker イメージをビルドしましょう:

docker build -t helloworld:1.1 .

注:以前のバージョンと区別するために、異なるバージョン(1.1)を使用しています。 古いバージョンをクリーンアップするには、以下のコマンドでコンテナ ID を取得します:

docker ps -a

次に、以下のコマンドでコンテナを削除します:

docker rm <old container id> --force

次にコンテナイメージ ID を取得します:

docker images | grep 1.0

最後に、以下のコマンドで古いイメージを削除できます:

docker image rm <old image id>

アプリケーションの実行

新しい Docker イメージを実行しましょう:

docker run --name helloworld \
--detach \
--expose 8080 \
--network=host \
helloworld:1.1

以下を使用してアプリケーションにアクセスできます:

curl http://localhost:8080/hello

トラフィックを生成するために上記のコマンドを数回実行しましょう。

1 分ほど経過したら、Splunk Observability Cloud に新しいトレースが表示されることを確認します。

あなたの特定の環境でトレースを探すことを忘れないでください。

トラブルシューティング

Splunk Observability Cloud にトレースが表示されない場合は、以下のようにトラブルシューティングを行うことができます。

まず、コレクター設定ファイルを編集用に開きます:

sudo vi /etc/otel/collector/agent_config.yaml

次に、トレースパイプラインにデバッグエクスポーターを追加します。これにより、トレースがコレクターログに書き込まれるようになります:

service:
  extensions: [health_check, http_forwarder, zpages, smartagent]
  pipelines:
    traces:
      receivers: [jaeger, otlp, zipkin]
      processors:
        - memory_limiter
        - batch
        - resourcedetection
      #- resource/add_environment
      # NEW CODE: デバッグエクスポーターをここに追加
      exporters: [otlphttp, signalfx, debug]

その後、コレクターを再起動して設定変更を適用します:

sudo systemctl restart splunk-otel-collector

journalctlを使用してコレクターログを表示できます:

ログの追跡を終了するには、Ctrl + C を押します。

sudo journalctl -u splunk-otel-collector -f -n 100
Last Modified 2025/06/17

K8sでOpenTelemetryコレクターをインストール

15 minutes  

ワークショップパート 1 の振り返り

ワークショップのこの時点で、以下を正常に完了しました:

  • Linux ホストに Splunk distribution of OpenTelemetry コレクターをデプロイ
  • Splunk Observability Cloud にトレースとメトリクスを送信するよう設定
  • .NET アプリケーションをデプロイし、OpenTelemetry で計装
  • .NET アプリケーションを Docker 化し、o11y cloud にトレースが流れることを確認

上記のステップを完了していない場合は、ワークショップの残りの部分に進む前に以下のコマンドを実行してください:

cp /home/splunk/workshop/docker-k8s-otel/docker/Dockerfile /home/splunk/workshop/docker-k8s-otel/helloworld/
cp /home/splunk/workshop/docker-k8s-otel/docker/entrypoint.sh /home/splunk/workshop/docker-k8s-otel/helloworld/

重要 これらのファイルがコピーされたら、/home/splunk/workshop/docker-k8s-otel/helloworld/Dockerfile を エディターで開き、Dockerfile の $INSTANCE をあなたのインスタンス名に置き換えてください。 インスタンス名は echo $INSTANCE を実行することで確認できます。

ワークショップパート 2 の紹介

ワークショップの次の部分では、Kubernetes でアプリケーションを実行したいと思います。 そのため、Kubernetes クラスターに Splunk distribution of OpenTelemetry コレクターを デプロイする必要があります。

まず、いくつかの重要な用語を定義しましょう。

重要な用語

Kubernetes とは何ですか?

「Kubernetes は、宣言的な設定と自動化の両方を促進する、コンテナ化されたワークロードとサービスを管理するためのポータブルで拡張可能なオープンソースプラットフォームです。」

Source: https://kubernetes.io/docs/concepts/overview/

Dockerfile に小さな修正を加えた後、アプリケーション用に以前ビルドした Docker イメージを Kubernetes クラスターにデプロイします。

Helm とは何ですか?

Helm は Kubernetes 用のパッケージマネージャーです。

「最も複雑な Kubernetes アプリケーションだとしても、定義、インストール、アップグレード役立ちます」

Helm を使用したコレクターのインストール

プロダクト内ウィザードではなくコマンドラインを使用して、コレクターをインストールするための独自の helmコマンドを作成しましょう。

まず、helm リポジトリを追加する必要があります:ます。」

Source: https://helm.sh/

Helm を使用して K8s クラスターに OpenTelemetry コレクターをデプロイします。

Helm の利点

  • 複雑性の管理
    • 数十のマニフェストファイルではなく、単一の values.yaml ファイルを扱う
  • 簡単な更新
    • インプレースアップグレード
  • ロールバックサポート
    • helm rollback を使用してリリースの古いバージョンにロールバック

ホストコレクターのアンインストール

先に進む前に、Linux ホストに先ほどインストールしたコレクターを削除しましょう: \

curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh;
sudo sh /tmp/splunk-otel-collector.sh --uninstall

Helm を利用して Collector をインストールする

ウィザードの代わりに、コマンドラインを利用して collector をインストールします。

まず初めに、Helm リポジトリに登録する必要があります

helm repo add splunk-otel-collector-chart https://signalfx.github.io/splunk-otel-collector-chart

リポジトリが最新であることを確認します:

helm repo update

helm チャートのデプロイメントを設定するために、/home/splunkディレクトリにvalues.yamlという名前の新しいファイルを作成しましょう:

# swith to the /home/splunk dir
cd /home/splunk
# create a values.yaml file in vi
vi values.yaml

Press ‘i’ to enter into insert mode in vi before pasting the text below. “i"を押下すると vi はインサートモードになります。ペースト前に押下してください

そして、下記のコードをコピーしてください

logsEngine: otel
agent:
  config:
    receivers:
      hostmetrics:
        collection_interval: 10s
        root_path: /hostfs
        scrapers:
          cpu: null
          disk: null
          filesystem:
            exclude_mount_points:
              match_type: regexp
              mount_points:
                - /var/*
                - /snap/*
                - /boot/*
                - /boot
                - /opt/orbstack/*
                - /mnt/machines/*
                - /Users/*
          load: null
          memory: null
          network: null
          paging: null
          processes: null

vi での変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

次のコマンドを使用してコレクターをインストールできます:

  helm install splunk-otel-collector --version 0.136.0 \
  --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
NAME: splunk-otel-collector
LAST DEPLOYED: Fri Dec 20 01:01:43 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Splunk OpenTelemetry Collector is installed and configured to send data to Splunk Observability realm us1.

コレクターが実行中であることを確認

以下のコマンドでコレクターが実行されているかどうかを確認できます:

kubectl get pods
NAME                                                         READY   STATUS    RESTARTS   AGE
splunk-otel-collector-agent-8xvk8                            1/1     Running   0          49s
splunk-otel-collector-k8s-cluster-receiver-d54857c89-tx7qr   1/1     Running   0          49s

O11y Cloud で K8s クラスターを確認

Splunk Observability Cloud で、Infrastructure -> Kubernetes -> Kubernetes Clustersにナビゲートし、 クラスター名($INSTANCE-cluster)を検索します:

Kubernetes node Kubernetes node

Last Modified 2025/09/08

アプリケーションをK8sにデプロイ

15 minutes  

Dockerfile の更新

Kubernetes では、環境変数は通常、Docker イメージに組み込むのではなく.yamlマニフェストファイルで管理されます。そこで、Dockerfile から以下の 2 つの環境変数を削除しましょう:

vi /home/splunk/workshop/docker-k8s-otel/helloworld/Dockerfile

次に、以下の 2 つの環境変数を削除します:

ENV OTEL_SERVICE_NAME=helloworld
ENV OTEL_RESOURCE_ATTRIBUTES='deployment.environment=otel-$INSTANCE'

vi での変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

新しい Docker イメージのビルド

環境変数を除外した新しい Docker イメージをビルドしましょう:

cd /home/splunk/workshop/docker-k8s-otel/helloworld

docker build -t helloworld:1.2 .

Note: we’ve used a different version (1.2) to distinguish the image from our earlier version. To clean up the older versions, run the following command to get the container id:

docker ps -a

Then run the following command to delete the container:

docker rm <old container id> --force

Now we can get the container image id:

docker images | grep 1.1

Finally, we can run the following command to delete the old image:

docker image rm <old image id>

Docker イメージを Kubernetes にインポート

通常であれば、Docker イメージを Docker Hub などのリポジトリにプッシュします。 しかし、今回のセッションでは、k3s に直接インポートする回避策を使用します。

cd /home/splunk

# Import the image into k3d
sudo k3d image import helloworld:1.2 --cluster $INSTANCE-cluster

.NET アプリケーションのデプロイ

ヒント:vi で編集モードに入るには「i」キーを押します。変更を保存するには、escキーを押してコマンドモードに入り、:wq!と入力してからenter/returnキーを押します。

.NET アプリケーションを K8s にデプロイするために、/home/splunkdeployment.yamlという名前のファイルを作成しましょう:

vi /home/splunk/deployment.yaml

そして以下を貼り付けます:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld
spec:
  selector:
    matchLabels:
      app: helloworld
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
        - name: helloworld
          image: docker.io/library/helloworld:1.2
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
          env:
            - name: PORT
              value: "8080"
Kubernetes における Deployment とは?

deployment.yaml ファイルは、deployment リソースを定義するために使用される kubernetes 設定ファイルです。このファイルは Kubernetes でアプリケーションを管理するための基盤となります!deployment 設定は deployment の 望ましい状態 を定義し、Kubernetes が 実際の状態 がそれと一致するよう保証します。これにより、アプリケーション pod の自己修復が可能になり、アプリケーションの簡単な更新やロールバックも可能になります。

次に、同じディレクトリにservice.yamlという名前の 2 つ目のファイルを作成します:

vi /home/splunk/service.yaml

そして以下を貼り付けます:

apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  type: ClusterIP
  selector:
    app: helloworld
  ports:
    - port: 8080
      protocol: TCP
Kubernetes における Service とは?

Kubernetes の Service は抽象化レイヤーであり、仲介者のような役割を果たします。Pod にアクセスするための固定 IP アドレスや DNS 名を提供し、時間の経過とともに Pod が追加、削除、または交換されても同じままです。

これらのマニフェストファイルを使用してアプリケーションをデプロイできます:

# create the deployment
kubectl apply -f deployment.yaml

# create the service
kubectl apply -f service.yaml
deployment.apps/helloworld created
service/helloworld created

アプリケーションのテスト

アプリケーションにアクセスするには、まず IP アドレスを取得する必要があります:

kubectl describe svc helloworld | grep IP:
IP:                10.43.102.103

その後、前のコマンドから返された Cluster IP を使用してアプリケーションにアクセスできます。 例:

curl http://10.43.102.103:8080/hello/Kubernetes

OpenTelemetry の設定

.NET OpenTelemetry 計装はすでに Docker イメージに組み込まれています。しかし、データの送信先を指定するためにいくつかの環境変数を設定する必要があります。

先ほど作成したdeployment.yamlファイルに以下を追加します:

重要 以下の YAML の$INSTANCEをあなたのインスタンス名に置き換えてください。 インスタンス名はecho $INSTANCEを実行することで確認できます。

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"

完全なdeployment.yamlファイルは以下のようになります($INSTANCEではなくあなたのインスタンス名を使用してください):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld
spec:
  selector:
    matchLabels:
      app: helloworld
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
        - name: helloworld
          image: docker.io/library/helloworld:1.2
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
          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"

以下のコマンドで変更を適用します:

kubectl apply -f deployment.yaml
deployment.apps/helloworld configured

その後、curlを使用してトラフィックを生成します。

1 分ほど経過すると、o11y cloud でトレースが流れているのが確認できるはずです。ただし、より早くトレースを確認したい場合は、以下の方法があります…

チャレンジ

開発者として、トレース ID を素早く取得するか、コンソールフィードバックを見たい場合、deployment.yaml ファイルにどのような環境変数を追加できるでしょうか?

答えを見るにはここをクリック

セクション 4「.NET Application を OpenTelemetry で計装する」のチャレンジで思い出していただければ、OTEL_TRACES_EXPORTER環境変数を使って trace を console に書き込むトリックをお見せしました。この変数を deployment.yaml に追加し、アプリケーションを再 deploy して、helloworld アプリから log を tail することで、trace id を取得して Splunk Observability Cloud で trace を見つけることができます。(ワークショップの次のセクションでは、debug exporter の使用についても説明します。これは K8s 環境でアプリケーションを debug する際の典型的な方法です。)

まず、vi で deployment.yaml ファイルを開きます:

vi deployment.yaml

次に、OTEL_TRACES_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=YOURINSTANCE"
  # NEW VALUE HERE:
  - name: OTEL_TRACES_EXPORTER
    value: "otlp,console"

変更を保存してからアプリケーションを再 deploy します:

kubectl apply -f deployment.yaml
deployment.apps/helloworld configured

helloworld の log を tail します:

kubectl logs -l app=helloworld -f
info: HelloWorldController[0]
      /hello endpoint invoked by K8s9
Activity.TraceId:            5bceb747cc7b79a77cfbde285f0f09cb
Activity.SpanId:             ac67afe500e7ad12
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        GET hello/{name?}
Activity.Kind:               Server
Activity.StartTime:          2025-02-04T15:22:48.2381736Z
Activity.Duration:           00:00:00.0027334
Activity.Tags:
    server.address: 10.43.226.224
    server.port: 8080
    http.request.method: GET
    url.scheme: http
    url.path: /hello/K8s9
    network.protocol.version: 1.1
    user_agent.original: curl/7.81.0
    http.route: hello/{name?}
    http.response.status_code: 200
Resource associated with Activity:
    splunk.distro.version: 1.8.0
    telemetry.distro.name: splunk-otel-dotnet
    telemetry.distro.version: 1.8.0
    os.type: linux
    os.description: Debian GNU/Linux 12 (bookworm)
    os.build_id: 6.2.0-1018-aws
    os.name: Debian GNU/Linux
    os.version: 12
    host.name: helloworld-69f5c7988b-dxkwh
    process.owner: app
    process.pid: 1
    process.runtime.description: .NET 8.0.12
    process.runtime.name: .NET
    process.runtime.version: 8.0.12
    container.id: 39c2061d7605d8c390b4fe5f8054719f2fe91391a5c32df5684605202ca39ae9
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.9.0
    service.name: helloworld
    deployment.environment: otel-jen-tko-1b75

次に、別の terminal window で curl コマンドを使って trace を生成します。log を tail している console で trace id が表示されるはずです。Activity.TraceId:の値をコピーして、APM の Trace 検索フィールドに貼り付けてください。

Last Modified 2025/10/27

OpenTelemetryコレクター設定のカスタマイズ

20 minutes  

デフォルト設定を使用して K8s クラスターに Splunk Distribution of OpenTelemetry コレクターを デプロイしました。このセクションでは、コレクター設定をカスタマイズする方法をいくつかの例で 説明します。

コレクター設定の取得

コレクター設定をカスタマイズする前に、現在の設定がどのようになっているかを どのように確認するのでしょうか?

Kubernetes 環境では、コレクター設定は Config Map を使用して保存されます。

以下のコマンドで、クラスターに存在する config map を確認できます:

kubectl get cm -l app=splunk-otel-collector
NAME                                                 DATA   AGE
splunk-otel-collector-otel-k8s-cluster-receiver   1      3h37m
splunk-otel-collector-otel-agent                  1      3h37m

なぜ 2 つの config map があるのでしょうか?

次に、以下のようにコレクターエージェントの config map を表示できます:

kubectl describe cm splunk-otel-collector-otel-agent
Name:         splunk-otel-collector-otel-agent
Namespace:    default
Labels:       app=splunk-otel-collector
              app.kubernetes.io/instance=splunk-otel-collector
              app.kubernetes.io/managed-by=Helm
              app.kubernetes.io/name=splunk-otel-collector
              app.kubernetes.io/version=0.113.0
              chart=splunk-otel-collector-0.113.0
              helm.sh/chart=splunk-otel-collector-0.113.0
              heritage=Helm
              release=splunk-otel-collector
Annotations:  meta.helm.sh/release-name: splunk-otel-collector
              meta.helm.sh/release-namespace: default

Data
====
relay:
----
exporters:
  otlphttp:
    headers:
      X-SF-Token: ${SPLUNK_OBSERVABILITY_ACCESS_TOKEN}
    metrics_endpoint: https://ingest.us1.signalfx.com/v2/datapoint/otlp
    traces_endpoint: https://ingest.us1.signalfx.com/v2/trace/otlp
    (followed by the rest of the collector config in yaml format)

K8s でコレクター設定を更新する方法

Linux インスタンスでコレクターを実行した以前の例では、コレクター設定は /etc/otel/collector/agent_config.yamlファイルで利用可能でした。その場合にコレクター設定を 変更する必要があれば、単純にこのファイルを編集し、変更を保存してから コレクターを再起動すればよかったのです。

K8s では、少し異なる動作をします。agent_config.yamlを直接変更する代わりに、 helm チャートをデプロイするために使用されるvalues.yamlファイルを変更することで コレクター設定をカスタマイズします。

GitHubの values.yaml ファイルには、 利用可能なカスタマイズオプションが記載されています。

例を見てみましょう。

Infrastructure Events Monitoring の追加

最初の例として、K8s クラスターの infrastructure events monitoring を有効にしましょう。

これにより、charts の Events Feed セクションの一部として Kubernetes イベントを確認できるようになります。 cluster receiver は、kubernetes-events monitor を使用して Smart Agent receiver で設定され、custom イベントを送信します。詳細についてはCollect Kubernetes eventsを参照してください。

これはvalues.yamlファイルに以下の行を追加することで実行されます:

ヒント:vi での開き方と保存方法は前のステップにあります。

logsEngine: otel
splunkObservability:
  infrastructureMonitoringEventsEnabled: true
agent:

ファイルが保存されたら、以下のコマンドで変更を適用できます:

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
Release "splunk-otel-collector" has been upgraded. Happy Helming!
NAME: splunk-otel-collector
LAST DEPLOYED: Fri Dec 20 01:17:03 2024
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
Splunk OpenTelemetry Collector is installed and configured to send data to Splunk Observability realm us1.

その後、config map を表示して変更が適用されたことを確認できます:

kubectl describe cm splunk-otel-collector-otel-k8s-cluster-receiver

smartagent/kubernetes-eventsが agent config に含まれていることを確認してください:

  smartagent/kubernetes-events:
    alwaysClusterReporter: true
    type: kubernetes-events
    whitelistedEvents:
    - involvedObjectKind: Pod
      reason: Created
    - involvedObjectKind: Pod
      reason: Unhealthy
    - involvedObjectKind: Pod
      reason: Failed
    - involvedObjectKind: Job
      reason: FailedCreate

これらの特定の変更が適用されるのは cluster receiver config map なので、そちらを指定していることに注意してください。

Debug Exporter の追加

collector に送信される trace と log を確認して、 Splunk に送信する前に検査したいとします。この目的のために debug exporter を使用できます。これは OpenTelemetry 関連の問題のトラブルシューティングに役立ちます。

values.yaml ファイルの下部に以下のように debug exporter を追加しましょう:

logsEngine: otel
splunkObservability:
  infrastructureMonitoringEventsEnabled: true
agent:
  config:
    receivers: ...
    exporters:
      debug:
        verbosity: detailed
    service:
      pipelines:
        traces:
          exporters:
            - debug
        logs:
          exporters:
            - 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
Release "splunk-otel-collector" has been upgraded. Happy Helming!
NAME: splunk-otel-collector
LAST DEPLOYED: Fri Dec 20 01:32:03 2024
NAMESPACE: default
STATUS: deployed
REVISION: 3
TEST SUITE: None
NOTES:
Splunk OpenTelemetry Collector is installed and configured to send data to Splunk Observability realm us1.

curl を使用してアプリケーションを数回実行してから、以下のコマンドで agent collector の log を tail します:

kubectl logs -l component=otel-collector-agent -f

以下のような trace が agent collector の log に書き込まれているのが確認できるはずです:

2024-12-20T01:43:52.929Z info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 2}
2024-12-20T01:43:52.929Z info ResourceSpans #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(78b452a43bbaa3354a3cb474010efd6ae2367165a1356f4b4000be031b10c5aa)
     -> 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.pod.ip: Str(10.42.0.15)
     -> k8s.pod.labels.app: Str(helloworld)
     -> k8s.pod.name: Str(helloworld-84865965d9-nkqsx)
     -> k8s.namespace.name: Str(default)
     -> k8s.pod.uid: Str(38d39bc6-1309-4022-a569-8acceef50942)
     -> k8s.node.name: Str(derek-1)
     -> k8s.cluster.name: Str(derek-1-cluster)

そして以下のような log エントリも確認できます:

2024-12-20T01:43:53.215Z info Logs {"kind": "exporter", "data_type": "logs", "name": "debug", "resource logs": 1, "log records": 2}
2024-12-20T01:43:53.215Z 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(78b452a43bbaa3354a3cb474010efd6ae2367165a1356f4b4000be031b10c5aa)
     -> 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)

ただし、Splunk Observability Cloud に戻ると、アプリケーションから trace と log が もはやそこに送信されていないことに気づくでしょう。

なぜそうなったと思いますか?次のセクションで詳しく説明します。

Last Modified 2025/06/17

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 エクスポーターのみがトレースとログのパイプラインに含まれています。 以前のトレースパイプライン設定にあったotlphttpsignalfxエクスポーターがなくなっています。 これが、もう 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 つのログエントリーが表示されています:

Duplicate Log Entries Duplicate Log Entries

これをどのように回避しますか?

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

# Import the image into k3d
sudo k3d image import helloworld:1.3 --cluster $INSTANCE-cluster

最後に、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 が含まれています:

JSON Format Logs JSON Format Logs

Last Modified 2025/10/27

Summary

2 minutes  

このワークショップでは、以下の概念についてハンズオンで体験しました:

  • Linux ホストにSplunk Distribution of the OpenTelemetry Collectorをデプロイする方法。
  • Splunk Distribution of OpenTelemetry .NETで.NET アプリケーションを計装する方法。
  • .NET アプリケーションを「Docker 化」し、Splunk Distribution of OpenTelemetry .NETで計装する方法。
  • Helm を使用して Kubernetes クラスターにSplunk Distribution of the OpenTelemetry Collectorをデプロイする方法。
  • コレクター設定をカスタマイズして問題をトラブルシューティングする方法。

他の言語と環境で OpenTelemetry がどのように計装されるかを確認するには、 Splunk OpenTelemetry Examples GitHub リポジトリをご覧ください。

将来このワークショップを独自に実行するには、これらの手順を参照して、Splunk Show のSplunk4Rookies - Observability ワークショップテンプレートを使用して EC2 インスタンスをプロビジョニングしてください。