📄
概念 📚 software-design-concepts

オブザーバビリティ

ログ・メトリクス・トレースの3本柱と分散トレーシングによるシステム可視化の実践

オブザーバビリティ(Observability)とは、システムの外部出力からその内部状態を推測できる能力を指す。「モニタリング」があらかじめ想定された異常を検知するのに対し、オブザーバビリティは予期しない問題の原因を事後に探索できる能力まで含む。複雑な分散システムでは障害の原因が複数のサービスにまたがることが多く、高いオブザーバビリティなくして迅速な問題解決は困難である。

オブザーバビリティの3本柱はLogs(ログ)・Metrics(メトリクス)・Traces(トレース)である。ログは個々のイベントを時系列で記録する。メトリクスは集計された数値データで、時系列グラフとして傾向を把握するために使う。トレースは一つのリクエストが複数のサービスをまたいで処理された際の経路と遅延を可視化する。この3つを相互に関連付けることで、問題の発見・原因特定・修正確認のサイクルを短縮できる。

OpenTelemetry(OTel)はLogs・Metrics・Tracesの収集・送信を標準化するCNCFのプロジェクトである。特定のベンダーに依存せず、Jaeger・Zipkin・Datadog・Grafana Tempoなど複数のバックエンドへデータを送出できる。新規プロジェクトではOpenTelemetryを基盤として採用することで、将来のツール変更コストを最小化できる。

コードレビューで着目するポイント

  • ログがJSON等の構造化形式(Structured Logging)で出力されているか(フリーテキストログは集計・検索が困難)
  • ログにrequestId・userId・traceIdなどの相関IDが含まれているか(複数ログの紐付けに必須)
  • メトリクスのカーディナリティが制御されているか(ユーザーIDをラベルにするとメモリが爆発する)
  • 分散トレースのspan が適切な粒度で計装されているか(外部呼び出し・DBクエリ・重要な処理単位)
  • SLO違反を検知するアラートが設定されているか(エラーバジェット消費率等)
  • ログレベル(DEBUG/INFO/WARN/ERROR)が適切に使い分けられているか
  • 個人情報(PII)がログに出力されていないか

典型的なアンチパターン

フリーテキストログ: log.info("User " + userId + " logged in") のような文字列連結ログは、機械的な集計・フィルタリングができない。{"event": "user_login", "user_id": "xxx"} のような構造化ログに統一すべきである。

高カーディナリティラベル: Prometheus 等でユーザーIDや注文IDをメトリクスのラベルにすると、時系列データが爆発的に増加してメモリ枯渇を引き起こす。カーディナリティの高い情報はトレースやログで扱い、メトリクスは集計値に留める。

トレース未連携のエラーログ: エラーログにtraceIdが含まれていないと、ログとトレースを手動で突き合わせる必要が生じ、原因調査に時間がかかる。相関IDは最初から全ログに埋め込む設計にすべきである。

参考リソース

  • 標準: OpenTelemetry - Logs・Metrics・Traces の標準化仕様と各言語のSDK
  • ツール: Jaeger - オープンソースの分散トレーシングシステム
  • ツール: Grafana Stack - Loki(ログ)・Prometheus(メトリクス)・Tempo(トレース)の統合プラットフォーム
  • 書籍: 「Observability Engineering」(Charity Majors et al.) - オブザーバビリティの思想と実践を体系的に解説
  • ツール: Datadog APM - 商用のオブザーバビリティプラットフォームのリファレンス実装