こんにちは!Observability(可観測性)の世界を探求する開発者の皆さん。OpenTelemetry(OTel)が事実上の標準として確立され、多くの方がOTelを導入されていることと思います。しかし、OTel SDKを使用しながら「一体内部でどんな部品がどのように動いているんだろう?」と疑問に思ったことはありませんか?🤔
今日は、まるで自動車のエンジンを分解するように、OpenTelemetry SDKを構成する最も重要な4つの主要コンポーネントについて深く掘り下げていきます。
さあ、OTel SDKのエンジンルームへ一緒に旅立ちましょう!

🕵️♀️ 環境探偵:Resource Detector
Resource Detectorは、その名の通り「リソース検出器」です。アプリケーションが起動する際、まるで探偵のように周囲の環境を徹底的に調査し、意味のある情報を自動的に収集する非常に賢い友人です。
- 主要な役割:自分がどこで実行されているか(AWS、GCP、Azure?)、コンテナ内で動いているか(Docker、Kubernetes?)、ホスト名は何であるかなどの環境情報を自動的に検知し、すべてのテレメトリーデータ(トレース、メトリクス、ログ)に共通の「タグ」として付与します。
- なぜ重要か?:この「タグ」情報のおかげで、「AWS us-east-1リージョンで実行中のpayment-serviceのv1.2バージョンで発生したエラー」のように、データをはるかに豊かなコンテキスト(Context)の中で分析することができます。コンテナIDやPod名が分かれば、問題が発生した特定のインスタンスを即座に特定できます。
Resource Detectorが収集する情報の例は以下の通りです。
- クラウド情報:cloud.provider, cloud.region, cloud.account.id
- コンテナ情報:container.name, container.id, container.image.name
- ホスト情報:host.name, host.arch
- OS情報:os.type, os.version
これらすべての情報が自動的に追加されるため、手動で設定する手間が大幅に削減されます。
📬 コンテキスト配達人:Propagator
Propagatorは、分散システム(MSA)において「コンテキスト(Context)伝播」という非常に重要な任務を遂行します。
- 主要な役割:MSA環境では、一つのリクエストが複数のサービス(サービスA -> サービスB -> サービスC)を経由して処理されます。このとき、これらのリクエストがすべて一つの作業(トレース)に属することを示す情報(トレースID、スパンIDなど)をサービス境界を越えて伝達する役割を果たします。まるで複数の国を旅する旅行者の「パスポート」のようなものです。
- 動作方式:
- Inject(注入):サービスAがサービスBを呼び出す際、HTTPヘッダーなどにtraceparentのような形でコンテキスト情報を注入します。
- Extract(抽出):サービスBはリクエストを受け取ると、ヘッダーからコンテキスト情報を抽出し、自身の作業がサービスAの作業に続いて継続していることを認識します。
- 主要な標準:W3C Trace Context(標準)、B3(過去に多く使用)などの合意されたフォーマットを使用します。
Propagatorのおかげで、私たちは複数のサービスに散らばっている断片的なスパンを、一つの美しい分散トランザクショングラフとして見ることができます。
🎟️ データゲートキーパー:Sampler
すべてのリクエストを追跡できれば良いのですが、トラフィックの多いサービスでは膨大な量のデータが発生し、それがコスト増加につながります。Samplerはまさにこの問題を解決するために存在します。
- 主要な役割:「どのリクエストを記録し、どのリクエストを破棄するか?」を決定するサンプリング戦略を担当します。つまり、データ収集の「ゲートキーパー」の役割を果たすわけです。
- 主要な戦略:
- AlwaysOnSampler:すべてのデータを記録します。(開発環境に有用)
- AlwaysOffSampler:すべてのデータを破棄します。
- TraceIdRatioBasedSampler:設定された比率(例:10%)に基づいてランダムにデータをサンプリングします。(最も一般的な方式)
- ParentBasedSampler:親スパンがサンプリングされた場合、子スパンもそれに従ってサンプリングするなど、親の決定に従います。
効果的なサンプリング戦略は、コストを削減しつつ、システムの状況を把握できる意味のあるデータを確保する上で非常に重要です。
🚚 データ最終配送ドライバー:Exporter
Exporterは、SDKパイプラインの最も最後の段階を担う「データ配送ドライバー」です。
- 主要な役割:アプリケーション内部で収集および処理されたテレメトリーデータを、最終的な分析システム(Backend)へエクスポート(Export)する役割を果たします。
- 多様な宛先:どの分析システムを使用するかによって、さまざまなExporterを選択できます。
- OTLP Exporter:OpenTelemetryの標準プロトコル(OTLP)を使用して、OTel CollectorやJaeger、Grafana Tempoなどに送信します。(最も推奨される方式)
- Jaeger Exporter:Jaegerフォーマットで直接送信します。
- Prometheus Exporter:Prometheusが収集できるフォーマットでメトリクスを公開します。
- Console Exporter:データを画面(コンソール)に出力します。(デバッグ用に最適!)
どのExporterを使用するかによって、私たちのデータの最終的な宛先が決定されます。
✨ 総まとめ:データの旅路
では、これらのコンポーネントがどのように連携して動作するのか、データの旅路をたどってまとめてみましょう。
- (開始)アプリケーションが実行されると、Resource Detectorが環境情報を収集し、基本的な「タグ」を準備します。🕵️♀️
- (リクエスト受信)外部からリクエストが来ると、PropagatorがHTTPヘッダーなどからトレースコンテキストを抽出します。📬
- (サンプリング決定)新しいトレースを開始する際、Samplerがこのトレースを記録するかどうかを決定します。🎟️
- (データ処理)アプリケーションコード内でスパンが生成され、これらのスパンには1で収集したリソース情報がすべて含まれます。
- (データ送信)処理が完了したデータ(スパン)は、Exporterを通じて最終的な宛先(例:Jaeger)へ配送されます。🚚
さて、最初の質問に戻ると、答えは明確になりました。実行環境の属性を「検出」するのは、Resource Detectorの固有の任務です。これら4つのコンポーネントの役割を明確に理解することで、皆さんのOpenTelemetry SDKの設定と活用能力がさらに一段階向上すると確信しています!
コメントを残す