トレース エクスポーター設定とOTLPプロトコル - Collector経由でのデータ送信 ​

OpenTelemetry Collectorの導入後、次に重要なのはトレースデータを効率的に送信することです。Collectorが受け取ったトレースデータを、どのようなプロトコルでバックエンドに送信するかは、システムの信頼性とパフォーマンスに大きく影響します。このセクションでは、OpenTelemetryの標準プロトコルであるOTLP(OpenTelemetry Protocol)の基本から、複数のバックエンドへの送信設定、そしてエクスポーターを最適化するためのベストプラクティスまで、実践的な知識を身につけていきます。

OTLPプロトコルの基本 ​

OTLPはOpenTelemetryプロジェクトで設計された汎用的なテレメトリデータ配信プロトコルです。トレース、メトリクス、ログ、プロファイルなど、複数の信号タイプをサポートし、クライアント側のSDKからCollectorへ、そしてCollectorからバックエンドシステムへと、テレメトリデータを信頼性高く送信するために必要なすべての機能を備えています。

gRPCとHTTP/JSONの2つの形式 ​

OTLPは2つの異なるトランスポート形式をサポートしています。どちらを選ぶかは、ネットワーク環境やシステム要件によって異なります。

gRPC形式はProtocol Buffersを使用し、ポート4317でリッスンするのが標準です。gRPCは複数の同時リクエストをサポートし、スケーラビリティに優れています。バイナリ形式であるため、ペイロードサイズが小さく、ネットワーク帯域幅の効率性を重視する場合に向いています。ただし、ファイアウォール越しの通信では制限されることがあるため、社内ネットワークでの利用が一般的です。

HTTP/JSON形式はポート4318でリッスンし、JSON形式またはバイナリProtobufの両方でのペイロード送信をサポートしています。HTTPベースのため、既存のファイアウォール構成をそのまま流用でき、トラブルシューティングも容易です。特にクラウド環境やHTTPプロキシを経由する必要がある環境では、HTTP形式の方が実用的です。

Protocol Buffers形式による効率的なシリアライゼーション ​

OTLPはペイロード形式としてProtocol Buffersを採用しています。これはGoogleが開発したシリアライゼーション形式で、JSONと比較してサイズがコンパクト、処理速度が高速、スキーマの進化に対応しやすいという特徴があります。

トレースデータはExportTraceServiceRequestというメッセージ型で定義されており、スパンの詳細情報(トレースID、スパンID、属性、イベント、ステータスなど)を構造化された形で送信します。この形式により、データの完全性を保ちながら、ネットワークオーバーヘッドを最小化できます。

Collectorへの直接送信とOTLPエクスポーター設定 ​

トレースデータをCollectorに送信する場合、OTLPエクスポーターを使用するのが最も一般的です。その設定方法と、パフォーマンスを調整するためのパラメータを理解することが重要です。

OTLPエクスポーターの基本設定 ​

Collectorの設定ファイルでOTLPエクスポーターを定義する場合、以下のような構造になります。

yaml
exporters:
  otlp:
    endpoint: collector.example.com:4317
    tls:
      ca_file: /etc/ssl/certs/ca.pem
      cert_file: /etc/ssl/certs/client.pem
      key_file: /etc/ssl/certs/client.key

endpointはCollectorのアドレスとポートを指定します。tlsセクションではセキュアな通信のための証明書を設定します。本番環境では必ずTLS暗号化を有効化し、クライアント証明書による相互認証(mTLS)を実装することが推奨されています。

バッチ処理のパラメータ調整 ​

トレースデータを効率的に送信するには、バッチ処理の設定が重要です。複数のスパンをまとめて送信することで、ネットワークトリップ回数を削減し、バックエンドの負荷を減らします。

yaml
processors:
  batch:
    send_batch_size: 1024
    timeout: 200ms
    send_batch_max_size: 2048

send_batch_size(デフォルト: 8192)はバッチを送信するトリガーとなるスパン数です。小さい値を設定するとレイテンシが低下し、大きい値を設定するとスループットが向上します。一般的には512〜1024程度が実用的な値です。

timeout(デフォルト: 200ms)はバッチサイズに達しなくても、この時間経過後は自動的にデータを送信します。低レイテンシが重要な場合は短く、スループット優先ならば長く設定します。本番環境では1〜5秒程度で調整することが多いです。

send_batch_max_sizeは単一バッチに含まれるデータポイント数の上限です。大量のデータが短時間に到着する場合に、バッチが大きくなりすぎるのを防ぎます。

再試行ポリシーとバックプレッシャー処理 ​

ネットワーク障害やバックエンドの一時的な問題に対応するため、OTLPエクスポーターには再試行メカニズムが組み込まれています。

yaml
exporters:
  otlp:
    endpoint: backend:4317
    retry_on_failure:
      enabled: true
      initial_interval: 100ms
      max_interval: 30s
      max_elapsed_time: 5m

retry_on_failureを有効化すると、送信失敗時に自動的に再試行が実行されます。initial_intervalは最初の再試行までの待機時間、max_intervalは再試行間隔の上限、max_elapsed_timeは総試行時間の上限です。これらを適切に設定することで、一時的なネットワーク障害に対する耐性が向上します。

バックプレッシャー処理は、Collector内部でエクスポーターの処理が追いつかない場合などに、パイプラインの上流(最終的にはレシーバー)でのデータ受け入れを制限または遅延させる機構です。これにより、Collector自体のメモリ枯渇やデータ喪失を防ぎます。

複数バックエンドへのエクスポート ​

実運用では、異なるトレーシングシステムに同時にデータを送信する必要が生じることがあります。Collectorはこのマルチバックエンド構成をサポートしており、各システムの要件に応じて最適な形式でデータを変換します。

Jaegerへの送信 ​

Jaegerは分散トレーシングプラットフォームで、複数の方式でトレースデータを受け取ることができます。

yaml
exporters:
  otlp/jaeger:
    endpoint: jaeger-collector:4317
    headers:
      authorization: "Bearer YOUR_TOKEN"

JaegerはOTLP gRPCネイティブでサポートしているため、OTLPエクスポーターを使用して直接データを送信できます。ポート4317がデフォルトです。これはJaegerへの送信を最も単純にする方法です。

yaml
exporters:
  jaeger/grpc:
    endpoint: jaeger-collector:14250

あるいは、Jaeger独自の形式で送信することも可能です。この場合はJaeger gRPC エクスポーターを使用し、ポート14250でリッスンするCollectorに送信します。

Zipkinへの送信 ​

Zipkinはオープンソースの分散トレーシングシステムで、独自のAPIでトレースを受け取ります。

yaml
exporters:
  zipkin:
    endpoint: "http://zipkin-server:9411/api/v2/spans"
    format: json

Zipkinエクスポーターはトレースデータを自動的にZipkin形式に変換し、HTTP POST経由で送信します。JSONまたはProtobuf形式の選択が可能ですが、JSONがより広くサポートされています。エンドポイントの/api/v2/spansは変更してはいけません。これはZipkinの標準APIパスです。

Datadogへの送信 ​

Datadogはクラウドベースの監視プラットフォームで、独自のトレース形式をサポートしています。

yaml
exporters:
  datadog:
    api:
      key: "YOUR_API_KEY"
      hostname: api.datadoghq.com

Datadogエクスポーターはトレースデータを自動的にDatadog形式に変換し、Datadogのバックエンド(通常はapi.datadoghq.com)に送信します。API キーはDatadog管理画面で生成する必要があります。リージョン(EU、US など)によってホスト名が異なるため、環境に応じて適切に設定してください。

AWS X-Rayへの送信 ​

AWS X-Rayはアマゾンウェブサービス(AWS)の分散トレーシングサービスです。

yaml
exporters:
  awsxray:
    region: "us-east-1"
    role_arn: "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"

X-Ray形式でエクスポートするにはawsxrayエクスポーターを使用します。AWS認証情報が必要で、IAM ロールまたはアクセスキーで設定します。リージョンを明示的に指定し、適切なIAM権限を持つロールを指定することが重要です。

エクスポーター設定のベストプラクティス ​

複数のトレーシングシステムを運用する場合、パフォーマンスと信頼性のバランスを取ることが重要です。効果的な設定を実現するために、いくつかのベストプラクティスがあります。

バッチサイズの最適化 ​

バッチサイズの選定は、ネットワーク帯域幅とレイテンシのバランスに影響します。

デフォルトの8192は高スループット環境向けです。低レイテンシが重要なシステムでは512〜1024に減らします。逆に、大量のトレースを扱う大規模システムでは、2048〜4096に増やしてスループットを優先します。

設定を決める際は、秒単位で到着するスパン数を見積もります。秒間10,000スパンの場合、バッチサイズを1024に設定すると、秒間約10バッチの送信が発生します。これは通常、許容できるレベルです。

タイムアウト設定の調整 ​

タイムアウトはレイテンシとスループットのトレードオフです。デフォルトの200msは適度に低いレイテンシを実現しますが、バッチサイズに達しない低スループット環境では頻繁な送信が発生します。

本番環境では1〜5秒程度のタイムアウトを設定することが推奨されています。これにより、バッチサイズに達するまで待機し、データ送信の効率を高めます。ただし、リアルタイムの問題検知が必要な場合は、タイムアウトを短くする必要があります。

スレッドプール数の設定 ​

Collectorは複数のエクスポーターを並行処理できます。スレッドプール数はCollectorのCPUリソースとメモリに応じて調整します。

yaml
exporters:
  otlp:
    endpoint: backend:4317
    sending_queue:
      num_consumers: 4

num_consumers(デフォルト: 自動調整)はエクスポーターのコンカレント送信数を制御します。マルチコアシステムでは、CPUコア数に応じて自動的に調整されるため、ほとんどの場合は明示的な設定は不要です。

トラブルシューティング ​

トレースデータが正しく送信されていない場合、いくつかの確認ステップがあります。

データが送信されていない場合の確認 ​

Collectorのログを確認し、エラーメッセージがないかチェックします。

bash
# Collectorログの確認
docker logs otel-collector 2>&1 | grep -i error

ログに「Connection refused」や「Timeout」といったメッセージが表示される場合は、ネットワーク接続またはエンドポイント設定に問題があります。バックエンドが正常に起動しているか、ファイアウォール設定に制限がないか確認してください。

Collectorが起動しているが、トレースデータが到着していない場合、debugエクスポーターを設定ファイルに追加し、実際のトレースがパイプラインを通過しているか確認できます。

yaml
exporters:
  debug:
    verbosity: detailed

バックプレッシャーによる遅延の対応 ​

メモリ制限に達するとCollectorはバックプレッシャーシグナルを送信し、クライアント側の送信速度を制限します。この場合、Collectorのメモリ制限を段階的に増やすか、バッチサイズを調整します。

yaml
processors:
  memory_limiter:
    limit_mib: 1024
    spike_limit_mib: 256

メモリ上限を物理メモリの30~50%程度に設定することが推奨されています。同時に、バッチサイズを減らしてメモリ消費を抑えることも効果的です。

ネットワーク断時の動作 ​

ネットワークが一時的に切断された場合、Collectorは再試行メカニズムにより自動的に接続を回復します。ただし、再試行期間内にバックエンドが復旧しない場合、データ喪失のリスクがあります。

長時間の停止に対応するため、Collector側にディスク上のキューを保持する設定も可能ですが、一般的には短い停止(分単位)であれば、デフォルトのメモリキューで十分です。

OpenTelemetryの標準プロトコルであるOTLPと、複数バックエンドへの対応を理解することで、トレーシングシステムの構築と運用がより堅牢になります。次のステップは、アプリケーション側のトレース計装です。Collectorの設定が完了したら、実際のアプリケーションコードでトレースを記録し、Collectorに送信する方法を学んでいきます。