Skip to content

分散トレーシングの概要

最終更新: February 20, 2026

はじめに

分散トレーシング(Distributed Tracing)は、マイクロサービスアーキテクチャにおいて、リクエストが複数の Service を通過する際の完全な経路を追跡する手法です。単一のリクエストが数十の Service を通過する可能性がある現代のシステムでは、分散トレーシングはパフォーマンスのボトルネックを特定し、問題をトラブルシューティングするために不可欠です。

分散トレーシングの必要性

従来のモニタリングの限界

マイクロサービス環境では、従来のログとメトリクスだけでは次の質問に答えられません。

  • リクエストはどの Service を通過したか?
  • 各 Service にはどのくらいの時間がかかったか?
  • エラーはどこで発生したか?
  • Service 間にはどのような依存関係があるか?

コアコンセプト

1. Trace

Trace は、単一のリクエストがたどる完全な経路を表します。リクエストがシステムを通過する際に生成されるすべての操作の集合です。

2. Span

Span は、作業の単一単位を表します。各 Span には次の情報が含まれます。

フィールド説明
TraceIDTrace 全体の一意な識別子abc123def456
SpanID個々の Span の一意な識別子span789
ParentSpanID親 Span の識別子span456
Operation Name操作の名前HTTP GET /api/users
Start Time開始タイムスタンプ2025-02-15T10:30:00Z
Duration所要時間150ms
Tagsメタデータhttp.status_code=200
Logsイベント記録error: connection timeout

3. Span の関係と階層

Span は親子関係を形成し、ツリー構造を作成します。

4. SpanContext

SpanContext は、Service 間で伝播される Trace 情報です。

yaml
# SpanContext Components
SpanContext:
  trace_id: "abc123def456789"      # Trace identifier
  span_id: "span789"               # Current Span identifier
  trace_flags: "01"                # Sampling flag
  trace_state: "vendor=value"      # Vendor-specific additional info

コンテキスト伝播

Service 間で Trace コンテキストを渡す方法です。

W3C Trace Context(推奨)

W3C 標準ヘッダーを使用した伝播:

http
# HTTP Request Headers
traceparent: 00-abc123def456789012345678901234-span12345678-01
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE

traceparent の形式:

version-trace_id-parent_id-trace_flags
00     -abc123...-span1234...-01

B3 伝播(Zipkin 互換)

Zipkin で使用される伝播形式:

http
# Single header format
b3: abc123def456789-span12345678-1-parent12345678

# Multi-header format
X-B3-TraceId: abc123def456789
X-B3-SpanId: span12345678
X-B3-ParentSpanId: parent12345678
X-B3-Sampled: 1

伝播形式の比較

形式ヘッダー利点欠点
W3C Trace Contexttraceparent, tracestate標準的、拡張可能比較的新しい
B3 Singleb3シンプル、単一ヘッダーZipkin 固有
B3 MultiX-B3-*デバッグが容易ヘッダーが多い
Jaegeruber-trace-idJaeger に最適化ベンダーロックイン

サンプリング戦略

すべてのリクエストをトレースすると、コストとパフォーマンスの問題が発生します。サンプリングはこれを管理します。

Head-based Sampling

リクエスト開始時にサンプリングを決定します。

利点:

  • 実装がシンプル
  • オーバーヘッドが低い
  • 一貫したサンプリング判断

欠点:

  • 重要なリクエストを見逃す可能性がある
  • エラーやレイテンシーを伴うリクエストをスキップする可能性がある

設定例:

yaml
# OpenTelemetry SDK Configuration
sampling:
  type: parentbased_traceidratio
  ratio: 0.1  # 10% sampling

Tail-based Sampling

リクエスト完了後に、結果に基づいてサンプリングを決定します。

利点:

  • 重要なリクエスト(エラー、レイテンシー)を見逃さない
  • よりインテリジェントなサンプリング
  • コスト効率が高い

欠点:

  • 実装が複雑
  • メモリ使用量が多い
  • すべての Span を一時的に保存する必要がある

OTEL Collector Tail Sampling の設定:

yaml
processors:
  tail_sampling:
    decision_wait: 10s
    num_traces: 100000
    policies:
      # Collect all error requests
      - name: errors
        type: status_code
        status_code:
          status_codes: [ERROR]
      # Collect slow requests
      - name: slow-requests
        type: latency
        latency:
          threshold_ms: 1000
      # 10% sampling for the rest
      - name: probabilistic
        type: probabilistic
        probabilistic:
          sampling_percentage: 10

サンプリング戦略の比較

戦略判断時点リソース使用量正確性ユースケース
Head-basedリクエスト開始時ほとんどのケース
Tail-basedリクエスト完了時エラー/レイテンシー重視
Adaptive動的トラフィック変動が大きい場合

Trace・Log・Metric の相関

TraceID による Log の関連付け

java
// Java logging example (SLF4J + MDC)
import org.slf4j.MDC;
import io.opentelemetry.api.trace.Span;

public void processOrder(Order order) {
    Span span = Span.current();
    MDC.put("traceId", span.getSpanContext().getTraceId());
    MDC.put("spanId", span.getSpanContext().getSpanId());

    logger.info("Processing order: {}", order.getId());
    // Log output: {"traceId": "abc123", "spanId": "span456", "message": "Processing order: 12345"}
}

Exemplars による Metric の関連付け

yaml
# Linking TraceID to Prometheus metrics
http_request_duration_seconds_bucket{le="0.5"} 1000 # {traceID="abc123"}
http_request_duration_seconds_bucket{le="1.0"} 1500 # {traceID="def456"}

Grafana での相関

ソリューションの比較

分散トレーシングソリューションの比較

機能TempoX-RayJaegerDatadog APMDynatrace
タイプオープンソースAWS マネージドオープンソース商用 SaaS商用 SaaS
ストレージObject StorageAWS 内部Cassandra/ESDatadogDynatrace
クエリ言語TraceQLFilter Expressions--DQL
サンプリングHead/TailルールベースHead動的動的
OTEL サポートネイティブネイティブネイティブネイティブネイティブ
Service MapGrafana 統合組み込み組み込み組み込み組み込み
AI 分析なしなしなしWatchdogDavis AI
コストストレージコストのみ使用量ベースインフラストラクチャコストHost/span ベースHost ベース
EKS 統合手動設定ネイティブ手動設定Agent デプロイOneAgent

選定ガイド

ベストプラクティス

1. Instrumentation 戦略

yaml
# Recommended instrumentation scope
instrumentation:
  # Always instrument
  always:
    - HTTP requests/responses
    - gRPC calls
    - Database queries
    - Message queue operations
    - External API calls

  # Optional instrumentation
  optional:
    - Internal function calls
    - Cache operations
    - File I/O

2. Span の命名規則

yaml
# Good examples
- "HTTP GET /api/users/{id}"
- "PostgreSQL SELECT users"
- "Redis GET user:123"
- "Kafka SEND orders"

# Bad examples
- "http call"
- "db query"
- "process"
- "span1"

3. Tag の標準化

yaml
# OpenTelemetry Semantic Conventions
tags:
  # HTTP
  http.method: GET
  http.url: https://api.example.com/users
  http.status_code: 200

  # Database
  db.system: postgresql
  db.statement: SELECT * FROM users
  db.operation: SELECT

  # Service
  service.name: user-service
  service.version: 1.2.3

次のステップ

分散トレーシングの概念を理解したら、以下のセクションで特定のツールの使用方法を学びます。

  • Grafana Tempo: Grafana スタックの分散トレーシングバックエンド
  • AWS X-Ray: AWS ネイティブの分散トレーシング
  • OpenTelemetry: 標準化された Instrumentation フレームワーク
  • Dynatrace: AI 搭載の APM ソリューション

クイズ

ツール固有のクイズで知識を確認しましょう。