OpenTelemetry実践導入ガイド:ログ・メトリクス・トレース統合を90日で定着させる

「監視は入れているのに障害原因の特定が遅い」。この状態は、たいていデータが足りないのではなく、データが分断されていることが原因です。メトリクスは見える、ログは別画面、トレースは導入途中、という構成だと、オンコールは毎回同じ調査を手作業で繰り返すことになります。

OpenTelemetry(OTel)はこの分断を減らすための共通規格です。ただし、導入に失敗するチームも少なくありません。理由は単純で、「計測の追加」だけやって「運用設計」を後回しにするからです。

本記事では、OpenTelemetry を 90 日で現場定着させるための、実務寄りの導入手順を紹介します。

1. まず決めるべき運用目標

OTel を入れる前に、次の問いに答えます。

  • どの障害をどれだけ早く見つけたいか
  • どのサービスの MTTR をどれだけ下げたいか
  • どのチームがトリアージ責任を持つか

たとえば「API 5xx の原因調査を 60 分 → 15 分に短縮する」と明文化すると、必要な計測が決まります。逆に目標がないと、span を増やす作業が目的化して終わります。

2. 参照アーキテクチャ

本番で扱いやすい最小構成は次です。

  1. アプリケーションに OTel SDK を導入
  2. エージェント/サイドカー経由で OTel Collector に送信
  3. Collector で加工・サンプリング・ルーティング
  4. Prometheus / Loki / Tempo(または商用基盤)へ出力

Collector を中継に置く理由は、アプリ側の再デプロイなしでルール変更できるからです。運用現場ではここが非常に効きます。

3. サービス命名規則を最初に固定する

命名規則を後で直すと、ダッシュボードとアラートが壊れます。以下は最低限のルール例です。

  • service.name: domain-service-env(例: billing-api-prod
  • deployment.environment: prod|stg|dev
  • service.version: Git SHA または semver
  • cloud.region: 実リージョン名

この 4 つが揃うと、障害時に「どの環境・どのバージョン」が悪いか一気に絞れます。

4. Pythonサービス計測の実装例

FastAPI を例に、最小導入手順を示します。

1
2
3
4
pip install opentelemetry-distro \
  opentelemetry-exporter-otlp \
  opentelemetry-instrumentation-fastapi \
  opentelemetry-instrumentation-requests

起動時に auto-instrumentation を有効化します。

1
2
3
4
5
6
7
export OTEL_SERVICE_NAME=billing-api-prod
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1

opentelemetry-instrument uvicorn app.main:app --host 0.0.0.0 --port 8080

次に、業務的に重要な処理へ custom span を追加します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from opentelemetry import trace

tracer = trace.get_tracer(__name__)

def charge_customer(order_id: str, customer_id: str, amount: int):
    with tracer.start_as_current_span("billing.charge") as span:
        span.set_attribute("order.id", order_id)
        span.set_attribute("customer.id", customer_id)
        span.set_attribute("payment.amount", amount)
        # 決済処理

HTTP 自動計測だけでは業務上のボトルネックが見えません。注文IDや課金金額など、調査に必要な属性を入れることが重要です。

5. Collector設定の実践パターン

Collector の典型構成は次です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
receivers:
  otlp:
    protocols:
      grpc:
      http:

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
  batch:
    send_batch_size: 1024
    timeout: 5s
  resource:
    attributes:
      - key: deployment.environment
        value: prod
        action: upsert

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true
  prometheusremotewrite:
    endpoint: http://mimir:9009/api/v1/push

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch, resource]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch, resource]
      exporters: [prometheusremotewrite]

ポイントは memory_limiterbatch を必ず入れることです。高負荷時の Collector 落ちを防げます。

6. サンプリング戦略

全トレースを保存すると費用が跳ねます。まずは次の段階運用が現実的です。

  • フェーズ1: 10% head sampling
  • フェーズ2: エラーは 100%、正常は 5%
  • フェーズ3: 高価値APIのみ 20%、その他 1%

さらに Collector で tail sampling を使うと、異常リクエストを優先的に残せます。導入初期は head sampling だけでも十分ですが、障害解析を重視するなら tail sampling への移行を計画に含めます。

7. ログとの相関を必ず作る

トレースだけ可視化しても、最終的にはログを見ます。ログに trace_id と span_id を埋め込み、画面から相互ジャンプできるようにします。

Python の標準 logging なら、フォーマッタに trace_id を追加するだけで改善します。アプリ基盤に共通 formatter を置いて強制するのが現実的です。

8. SLO/アラート設計の接続

OTel 導入の価値は、可視化だけでなく SLO 運用に繋がる点です。例:

  • SLI: http.server.duration の p95
  • SLI: http.server.request.count に対する 5xx 率
  • エラーバジェット消費率が閾値超過でページ

ここで重要なのは、アラート本文に「関連トレースのリンク」を入れることです。オンコールが即座に原因調査へ入れます。

9. 90日導入ロードマップ

Day 1-14: 土台づくり

  • 命名規則決定
  • Collector を冗長構成で配置
  • 主要 2 サービスへ SDK 導入

Day 15-45: 運用化

  • 主要 API の custom span 追加
  • ダッシュボード標準化
  • エラー系アラートにトレースリンクを追加

Day 46-90: 最適化

  • サンプリング改善(費用最適化)
  • ノイズアラート削減
  • 週次レビューで MTTR 変化を追跡

この 90 日で「導入しただけ」から「使って解決できる」状態に変わります。

10. よくある失敗と対策

失敗1: span を増やしすぎて遅くなる

対策: 重要フローに限定し、属性も最小から始める。

失敗2: PII を属性に入れてしまう

対策: Collector でマスキング、アプリ側で禁止 lint を導入。

失敗3: ダッシュボードがチームごとにバラバラ

対策: プラットフォーム側で共通テンプレートを配布し、必須指標を統一。

11. 導入チェックリスト

  • service.name / deployment.environment / service.version が揃っている
  • Collector に memory_limiterbatch が入っている
  • トレースとログが trace_id で相関できる
  • エラー率アラートからトレースへ遷移できる
  • サンプリング率と月次コストをレビューしている
  • 主要障害のポストモーテムで観測改善が反映される

OpenTelemetry は魔法のツールではありません。しかし、計測規約と運用フローをセットで設計すると、障害対応の速度と質は確実に上がります。まずは 2 サービスで勝ち筋を作り、そこから全体展開するのが最短ルートです。