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