トレース エクスポーター設定と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エクスポーターを定義する場合、以下のような構造になります。
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.keyendpointはCollectorのアドレスとポートを指定します。tlsセクションではセキュアな通信のための証明書を設定します。本番環境では必ずTLS暗号化を有効化し、クライアント証明書による相互認証(mTLS)を実装することが推奨されています。
バッチ処理のパラメータ調整
トレースデータを効率的に送信するには、バッチ処理の設定が重要です。複数のスパンをまとめて送信することで、ネットワークトリップ回数を削減し、バックエンドの負荷を減らします。
processors:
batch:
send_batch_size: 1024
timeout: 200ms
send_batch_max_size: 2048send_batch_size(デフォルト: 8192)はバッチを送信するトリガーとなるスパン数です。小さい値を設定するとレイテンシが低下し、大きい値を設定するとスループットが向上します。一般的には512〜1024程度が実用的な値です。
timeout(デフォルト: 200ms)はバッチサイズに達しなくても、この時間経過後は自動的にデータを送信します。低レイテンシが重要な場合は短く、スループット優先ならば長く設定します。本番環境では1〜5秒程度で調整することが多いです。
send_batch_max_sizeは単一バッチに含まれるデータポイント数の上限です。大量のデータが短時間に到着する場合に、バッチが大きくなりすぎるのを防ぎます。
再試行ポリシーとバックプレッシャー処理
ネットワーク障害やバックエンドの一時的な問題に対応するため、OTLPエクスポーターには再試行メカニズムが組み込まれています。
exporters:
otlp:
endpoint: backend:4317
retry_on_failure:
enabled: true
initial_interval: 100ms
max_interval: 30s
max_elapsed_time: 5mretry_on_failureを有効化すると、送信失敗時に自動的に再試行が実行されます。initial_intervalは最初の再試行までの待機時間、max_intervalは再試行間隔の上限、max_elapsed_timeは総試行時間の上限です。これらを適切に設定することで、一時的なネットワーク障害に対する耐性が向上します。
バックプレッシャー処理は、Collector内部でエクスポーターの処理が追いつかない場合などに、パイプラインの上流(最終的にはレシーバー)でのデータ受け入れを制限または遅延させる機構です。これにより、Collector自体のメモリ枯渇やデータ喪失を防ぎます。
複数バックエンドへのエクスポート
実運用では、異なるトレーシングシステムに同時にデータを送信する必要が生じることがあります。Collectorはこのマルチバックエンド構成をサポートしており、各システムの要件に応じて最適な形式でデータを変換します。
Jaegerへの送信
Jaegerは分散トレーシングプラットフォームで、複数の方式でトレースデータを受け取ることができます。
exporters:
otlp/jaeger:
endpoint: jaeger-collector:4317
headers:
authorization: "Bearer YOUR_TOKEN"JaegerはOTLP gRPCネイティブでサポートしているため、OTLPエクスポーターを使用して直接データを送信できます。ポート4317がデフォルトです。これはJaegerへの送信を最も単純にする方法です。
exporters:
jaeger/grpc:
endpoint: jaeger-collector:14250あるいは、Jaeger独自の形式で送信することも可能です。この場合はJaeger gRPC エクスポーターを使用し、ポート14250でリッスンするCollectorに送信します。
Zipkinへの送信
Zipkinはオープンソースの分散トレーシングシステムで、独自のAPIでトレースを受け取ります。
exporters:
zipkin:
endpoint: "http://zipkin-server:9411/api/v2/spans"
format: jsonZipkinエクスポーターはトレースデータを自動的にZipkin形式に変換し、HTTP POST経由で送信します。JSONまたはProtobuf形式の選択が可能ですが、JSONがより広くサポートされています。エンドポイントの/api/v2/spansは変更してはいけません。これはZipkinの標準APIパスです。
Datadogへの送信
Datadogはクラウドベースの監視プラットフォームで、独自のトレース形式をサポートしています。
exporters:
datadog:
api:
key: "YOUR_API_KEY"
hostname: api.datadoghq.comDatadogエクスポーターはトレースデータを自動的にDatadog形式に変換し、Datadogのバックエンド(通常はapi.datadoghq.com)に送信します。API キーはDatadog管理画面で生成する必要があります。リージョン(EU、US など)によってホスト名が異なるため、環境に応じて適切に設定してください。
AWS X-Rayへの送信
AWS X-Rayはアマゾンウェブサービス(AWS)の分散トレーシングサービスです。
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リソースとメモリに応じて調整します。
exporters:
otlp:
endpoint: backend:4317
sending_queue:
num_consumers: 4num_consumers(デフォルト: 自動調整)はエクスポーターのコンカレント送信数を制御します。マルチコアシステムでは、CPUコア数に応じて自動的に調整されるため、ほとんどの場合は明示的な設定は不要です。
トラブルシューティング
トレースデータが正しく送信されていない場合、いくつかの確認ステップがあります。
データが送信されていない場合の確認
Collectorのログを確認し、エラーメッセージがないかチェックします。
# Collectorログの確認
docker logs otel-collector 2>&1 | grep -i errorログに「Connection refused」や「Timeout」といったメッセージが表示される場合は、ネットワーク接続またはエンドポイント設定に問題があります。バックエンドが正常に起動しているか、ファイアウォール設定に制限がないか確認してください。
Collectorが起動しているが、トレースデータが到着していない場合、debugエクスポーターを設定ファイルに追加し、実際のトレースがパイプラインを通過しているか確認できます。
exporters:
debug:
verbosity: detailedバックプレッシャーによる遅延の対応
メモリ制限に達するとCollectorはバックプレッシャーシグナルを送信し、クライアント側の送信速度を制限します。この場合、Collectorのメモリ制限を段階的に増やすか、バッチサイズを調整します。
processors:
memory_limiter:
limit_mib: 1024
spike_limit_mib: 256メモリ上限を物理メモリの30~50%程度に設定することが推奨されています。同時に、バッチサイズを減らしてメモリ消費を抑えることも効果的です。
ネットワーク断時の動作
ネットワークが一時的に切断された場合、Collectorは再試行メカニズムにより自動的に接続を回復します。ただし、再試行期間内にバックエンドが復旧しない場合、データ喪失のリスクがあります。
長時間の停止に対応するため、Collector側にディスク上のキューを保持する設定も可能ですが、一般的には短い停止(分単位)であれば、デフォルトのメモリキューで十分です。
OpenTelemetryの標準プロトコルであるOTLPと、複数バックエンドへの対応を理解することで、トレーシングシステムの構築と運用がより堅牢になります。次のステップは、アプリケーション側のトレース計装です。Collectorの設定が完了したら、実際のアプリケーションコードでトレースを記録し、Collectorに送信する方法を学んでいきます。