はじめに
マイクロサービスやクラウドネイティブな開発が普及する中で、システムの状態を正しく把握し、障害時に素早く対応するための「オブザーバビリティ(可観測性)」が注目されています。
この記事では、オブザーバビリティの重要な要素である「トレース(Tracing)」について、初学者にも理解できるように図解イメージや具体例、簡単なサンプルコードなどを使って詳しく解説します。
🧭 まずはオブザーバビリティの基本を押さえよう
💡 オブザーバビリティとは?
「オブザーバビリティ(Observability)」とは、システムの内部状態を外部から把握する力を指します。簡単に言えば、何か問題が起きたときに“なぜ”それが起きたかを把握するための力です。
🔑 オブザーバビリティの3つの柱
| 🧩 種類 | 説明 | 例 |
|---|---|---|
| 📄 ログ(Logs) | イベントやエラーの詳細なテキスト記録 | エラー内容、スタックトレースなど |
| 📊 メトリクス(Metrics) | 数値として可視化できる定量データ | CPU使用率、リクエスト数、レイテンシなど |
| 🧵 トレース(Traces) | 処理の流れを追跡する情報 | 1つのリクエストが通ったサービス一覧とその処理時間 |
🧵 トレースとは何か?もう少し詳しく
🔍 トレースの目的
トレースの目的は、以下のような疑問に答えることです:
- このリクエストはどのサービスを通って処理された?
- どこで遅延やエラーが発生した?
- 各処理にどれくらい時間がかかっている?
🗺️ イメージ:ユーザー操作とトレース
例えば、あなたがECサイトで「商品購入」ボタンを押した場合の裏側では、以下のような複数サービスが連携しています:
ユーザー → Webサーバー
↓
認証サービス
↓
商品サービス
↓
在庫チェックサービス
↓
決済サービス
↓
通知サービス(メール・SMS)
この一連の流れを1本の「Trace」として記録し、各ステップを「Span」として細かく分解して追跡します。
🧩 トレースの構造と用語解説
✅ 用語まとめ
| 用語 | 説明 |
|---|---|
| Trace | 1つのユーザーリクエスト全体の処理の流れ(親) |
| Span | 1つ1つの処理単位(子)。各サービスやメソッド単位で記録 |
| Context | TraceとSpanの関係性を保持するための情報 |
| Parent/Child関係 | Spansは親子構造でネストされ、呼び出しの流れを再現可能 |
🧱 トレース構造の図解(テキストベース)
Trace: 商品購入リクエスト
├── Span: Webサーバーの処理(500ms)
│ ├── Span: 認証サービス(150ms)
│ ├── Span: 商品情報取得(200ms)
│ │ └── Span: 在庫チェック(50ms)
│ ├── Span: 決済処理(1000ms)
│ └── Span: 通知サービス(300ms)
これを見ると、決済処理が最も時間がかかっていることがすぐにわかります。
⚠️ 初心者が誤解しやすいポイント
| 誤解しやすい点 | 正しい理解 |
|---|---|
| トレース=ログ? | 違います。ログは断片的な記録、トレースは流れ全体を可視化します。 |
| トレースは遅い? | 適切に設定すればパフォーマンスに大きな影響はありません。 |
| 全部の処理をトレースすべき? | コストやパフォーマンスを考慮してサンプリングも可能です。 |
🛠️ トレースを支える代表的な技術
🔧 トレーシングツール比較
| ツール名 | 特徴 | 向いているケース |
|---|---|---|
| Jaeger | CNCF配下、分かりやすいUI、拡張性◎ | Kubernetesなどクラウドネイティブ環境 |
| Zipkin | 軽量、導入が簡単 | 小規模プロジェクトや開発段階 |
| AWS X-Ray | AWS連携が簡単、GUI強力 | AWS利用しているチーム |
🌐 OpenTelemetryとは?
OpenTelemetry(略称:OTel)は、ログ・メトリクス・トレースを統一的な方法で収集・送信・表示できる標準仕様です。
- ベンダーロックインを避けられる
- 多くの言語・ライブラリ・フレームワークに対応
- JaegerやPrometheusなどと連携可能
💻 サンプルコード:Flask + OpenTelemetry
初心者向けに、最もシンプルな例として Flaskアプリにトレース機能を追加してみます。
📦 必要なパッケージ
pip install flask opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-exporter-console
📝 コード例
from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
# トレーサーの設定
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
trace.get_tracer_provider().add_span_processor(
SimpleSpanProcessor(ConsoleSpanExporter())
)
# Flaskアプリ初期化
app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
@app.route("/")
def index():
return "Hello, Tracing!"
@app.route("/process")
def process():
with tracer.start_as_current_span("custom-span"):
return "Processing..."
if __name__ == "__main__":
app.run(debug=True)
📌 実行結果(ターミナル)
Span(name="custom-span", context=..., kind=SpanKind.INTERNAL, ...)
これだけで、処理のトレースが確認できるようになります!
🔎 トレースの導入ステップ
- 対象アプリにSDKやエージェントを組み込む
- 必要なスパンを手動・自動で挿入
- エクスポーターでデータを可視化ツールへ送信
- JaegerやGrafanaで可視化・分析
- アラートや異常検知に活用
📈 トレースの活用シーンと効果
🧩 具体的なユースケース
| シーン | トレースでできること |
|---|---|
| パフォーマンス改善 | 遅延の原因を特定し、ボトルネックを排除 |
| 障害対応 | エラーがどのサービス・処理で発生したか素早く追跡 |
| 品質向上 | テスト環境や本番環境の振る舞いを継続的に可視化 |
✅ トレースとアラートの連携(例:Slack通知)
トレースを導入しただけでは、「見える化」だけにとどまり、問題の発見には能動的なチェックが必要です。
そこで重要なのが「アラートとの連携」です。
🎯 目的
- エラーや遅延など、問題を自動で検出し通知することで、素早く対応できるようにする
- 通知をSlackなどに送ることで、チーム全体での可視性が上がる
🧭 全体構成イメージ
アプリケーション
↓ トレース収集(例:OpenTelemetry)
↓ エクスポート(例:Jaeger、Tempo)
↓ メトリクスに変換(例:Prometheus)
↓ アラート条件を設定(例:Alertmanager)
↓ Slackなどに通知
🛠️ 具体的な構成例(OpenTelemetry + Prometheus + Alertmanager + Slack)
📦 使用するツール
| ツール名 | 役割 |
|---|---|
| OpenTelemetry | トレースデータの収集 |
| Prometheus | メトリクスの収集(tracesをmetricsに変換) |
| Alertmanager | アラートの管理と通知 |
| Slack | 通知先チャットツール |
🧪 トレースからメトリクスへの変換
多くのアラートは「メトリクス」を元に設定されるため、トレースデータをメトリクス化する必要があります。
OpenTelemetry Collector や Tempo などを使うことで、次のような指標を生成可能:
http_server_duration_secondsrpc_server_duration_secondstrace_latency_buckettrace_errors_total
🧯 Prometheusでアラートルールを設定
たとえば、500エラーが多発している場合に通知を送る例です。
groups:
- name: trace_alerts
rules:
- alert: HighErrorRate
expr: increase(trace_errors_total[1m]) > 5
for: 1m
labels:
severity: critical
annotations:
summary: "エラーが多発しています"
description: "直近1分間で{{ $value }}件のエラーが発生しました。"
🔔 AlertmanagerでSlack通知を設定
1. SlackのIncoming Webhookを作成
Slackの「App」設定画面から Webhook URL を取得します。
2. alertmanager.yml にSlack通知を設定
global:
slack_api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
route:
receiver: 'slack-notifications'
receivers:
- name: 'slack-notifications'
slack_configs:
- channel: '#alerts'
text: '{{ .CommonAnnotations.summary }}\n{{ .CommonAnnotations.description }}'
✅ 通知の例(Slack画面)
🚨 エラーが多発しています
直近1分間で6件のエラーが発生しました。
このように、リアルタイムでチームにアラートを通知できるため、トラブルの早期発見と共有が容易になります。
💡 よくある通知条件の例
| 条件 | 表現例(PromQL) |
|---|---|
| レイテンシが高い | histogram_quantile(0.95, rate(http_server_duration_seconds_bucket[5m])) > 1 |
| エラー数が一定を超えた | increase(trace_errors_total[1m]) > 5 |
| トレースの数が急減 | rate(trace_total[1m]) < 1 |
🧠 補足:ログベース通知との違い
| 項目 | トレースアラート | ログアラート |
|---|---|---|
| 対象 | 処理の流れ・遅延・失敗 | エラーメッセージ・例外情報 |
| 粒度 | ミリ秒単位で時系列解析可能 | イベントベースで断片的 |
| 可視性 | サービス間の関係も含めて把握可能 | 単一サービス視点になりやすい |
📬 アラート連携のまとめ
| 項目 | 内容 |
|---|---|
| トレースとアラートの連携 | トレースからメトリクスを生成し、PrometheusとAlertmanagerでSlack通知可能にする |
| 通知先 | Slack, Teams, PagerDutyなどに対応可能 |
| メリット | 問題発生時にリアルタイムでチームに共有、迅速な対応が可能 |
| 注意点 | トレース → メトリクス変換が必要、アラートのしきい値設計が重要 |
🚀 次にやってみよう!
- ✅ Slack通知の動作テストをする
- ✅ アラート条件を段階的に調整(info → warning → critical)
- ✅ Grafanaと連携して可視化+通知の一体化も検討
📚 全体まとめ
| ポイント | 詳細 |
|---|---|
| ✅ トレースとは? | リクエストの処理の流れを追跡するための仕組み |
| ✅ なぜ必要? | 分散システムでは何が起きたかを把握するのが難しいため |
| ✅ 用語整理 | Trace(全体)、Span(処理単位)、Context(つなぎ役) |
| ✅ ツール | Jaeger、Zipkin、OpenTelemetry、AWS X-Rayなど |
| ✅ 初期導入方法 | SDKを使って簡単に導入可能(例:Flask + OTel) |
| ✅ 効果 | パフォーマンス改善・障害対応・品質向上 |
🏁 おわりに
「トレース」は一見難しそうに見えるかもしれませんが、実際に導入してみるとシステム全体の可視化に非常に役立ちます。
特にマイクロサービスや分散アーキテクチャを採用しているプロジェクトでは、もはや必須の監視手法といっても過言ではありません。
ぜひ、まずは小さなプロジェクトから試して、オブザーバビリティの世界を体験してみてください!