【ITニュース解説】Observability: Making an Invoice Request Explain Itself
2026年10月01日に「Dev.to」が公開したITニュース「Observability: Making an Invoice Request Explain Itself」について初心者にもわかりやすく解説しています。
ITニュース概要
Observabilityとは、システム内部の動きを可視化し、問題の原因を特定する技術だ。請求処理を例に、ログで個々のイベント、メトリクスで全体傾向、トレースで特定の処理経路を追跡することで、どこで遅延やエラーが発生したかを明確にする方法を解説している。
ITニュース解説
システム開発において、アプリケーションが期待通りに動作しているか、もし問題が発生した場合にその原因を迅速に特定できるかは非常に重要だ。この「システムの内部で何が起こっているかを理解できる能力」を「オブザーバビリティ(可観測性)」と呼ぶ。オブザーバビリティは、単にシステムが動いているかどうかだけでなく、「なぜ遅いのか」「何が原因でエラーになったのか」といった、より深い問いに答えるための強力なツールとなる。
従来の監視では、例えばウェブサイトが応答しているか、サーバーのCPU使用率が高いかといった、システム全体の健全性や外部から見える挙動をチェックすることが主だった。しかし、現代の複雑な分散システムでは、あるエンドポイントが「正常に応答した」というだけでは不十分なケースが多い。請求書発行の処理を例に考えてみよう。ユーザーが請求書の発行をリクエストし、「成功しました」という応答が返ってきたとしても、そのリクエストが内部でどのように処理され、どれくらいの時間がかかったのか、そしてもし遅延があったなら、どの部分で時間がかかったのかまでは、この応答だけではわからない。
ここで、オブザーバビリティが活躍する。記事では、「安全でないサービス」と「安全なサービス」を対比させて説明している。「安全でないサービス」は、処理が完了したという結果や、一般的なエラーログしか出力しない。リクエストを特定するためのIDはあったとしても、そのリクエストが内部で具体的に何をしたのか、どのような依存サービスと連携したのか、それぞれの処理にどれくらいの時間がかかったのかといった詳細な情報は得られないため、問題が発生した際に調査が非常に難しい。
一方で、「安全なサービス」は、構造化されたログ、メトリクス、そしてトレースという三種類の「テレメトリデータ」を生成する。これらは、ビジネスロジックの実行速度を直接速くするわけではないが、問題発生時の調査能力を格段に向上させる。この三つの要素は、オブザーバビリティの「三本柱」とも呼ばれる。
まず、「ログ」は、システム内で発生した個別のイベントを記録する。例えば、請求書処理フローにおいて、データベースから請求書を読み込んだ、在庫を予約した、PDFを生成したといった各工程が完了した時に、その工程の名前、かかった時間、結果(成功か失敗か)などの詳細を構造化された形式で記録する。もしエラーが発生した場合は、そのエラーの内容も記録される。ログは、ある特定の瞬間に何が起こったのかを詳細に把握するのに役立つ。
次に、「メトリクス」は、時間とともに変化する数値の集計データだ。リクエストの総数、平均的な応答時間、エラーの発生回数、現在処理中のリクエスト数などがメトリクスとして収集される。これらは、大量のリクエストをまとめて統計的に分析するのに適しており、システム全体のトレンドや異常を検出するのに役立つ。例えば、「最近、全体のリクエストの応答時間が長くなっている」といった傾向はメトリクスから読み取れる。ただし、メトリクスだけでは「どのリクエストのどの部分が遅いのか」という具体的な原因までは特定できない。
最後に、「トレース」は、単一のリクエストがシステム内をどのように伝播し、どのような処理を経て完了したかを示すものだ。これは、リクエストが開始されてから完了するまでの間に実行された一連の操作を、親子関係を持つ「スパン」と呼ばれる単位で階層的に可視化する。例えば、HTTPリクエストを受け取ったところから始まり、請求書のロード、在庫予約、手数料計算、PDF生成、通知送信といった各依存サービスの呼び出しまでがそれぞれスパンとして記録され、それぞれのスパンにかかった時間がわかる。トレースは、特定の遅いリクエストや失敗したリクエストが、どの処理ステップで時間を費やしたのか、あるいはどこでエラーになったのかをピンポイントで特定するのに非常に有効だ。
これらのログ、メトリクス、トレースはそれぞれ異なる役割を持ち、互いに補完し合う関係にある。メトリクスでシステム全体のパフォーマンスの変化を検出し、その変化が特定の時点やリクエストで発生したものであれば、トレースを使ってそのリクエストの内部の詳細な処理経路と時間を追跡する。さらに、トレースで特定された遅い処理ステップについて、ログを参照することで、そのステップで何が起こっていたのかを具体的なイベントレベルで確認する。これら三つが揃って初めて、システムが「自分自身を説明」できるようになるのだ。
記事では、請求書処理のワークフローを例に、その具体的な効果を示している。このワークフローは、「請求書の読み込み」「在庫予約」「手数料計算」「PDF生成」「通知送信」という五つの依存サービス操作で構成される。通常であれば、これらの処理は合計で約95ミリ秒で完了するように設定されている。しかし、「PDF生成」の工程に意図的に長い遅延(例えば4800ミリ秒)を導入すると、リクエスト全体の処理時間は数秒に及ぶ。この時、単なる「リクエストが数秒かかった」という情報だけでなく、トレースを見ることで「PDF生成がリクエストのほとんどの時間を消費した」という具体的な原因を突き止めることができる。これが、オブザーバビリティがもたらす価値の核心だ。
さらに、オブザーバビリティを機能させるためには、「コンテキストの伝達」が非常に重要となる。リクエストが複数のサービスやコンポーネントをまたいで処理される際、そのリクエストの「トレースID」や「スパンID」といった識別情報が、呼び出し元のサービスから呼び出されるサービスへと確実に引き継がれる必要がある。これにより、全体のリクエストの流れが途切れることなく追跡できるようになる。Go言語のサービスでは、コンテキストオブジェクトを通じてこの情報が伝達され、エラーが発生した場合も、関連するスパンにエラー情報が記録され、処理は適切に停止される。また、エラーはHTTPハンドラによって適切なステータスコード(例:504ゲートウェイタイムアウト、499クライアントクローズドリクエストなど)にマッピングされるが、詳細なエラー情報はログやトレースに残されることで、システムの外部には一般的なエラーメッセージを返しつつ、内部では詳しい原因を追跡できる仕組みになっている。
イベントを関連付けるために、ログにはrequest_idや、もし有効なスパンが存在すればtrace_idとspan_idを含める。request_idはHTTP応答とログを紐付け、trace_idは一つの実行に関連する全てのスパンをグループ化し、span_idはそのトレース内の特定の操作を識別する。重要なのは、これらの詳細なIDをメトリクスのラベル(分類のためのキー)としては使用しないことだ。メトリクスは集計情報であるため、個々のリクエストIDを含めると、メトリクスデータの量が膨大になり、集計の効率が落ちてしまう。そのため、メトリクスはメソッド、ルーティングテンプレート(例:/invoices/{id}/processのように具体的なIDではなくパターン)、ステータスクラスといった、より汎用的なラベルで集計される。これにより、集計メトリクスのパフォーマンスを維持しつつ、詳細なリクエストレベルの調査はログとトレースに委ねるという役割分担が実現される。
システムの各メトリクス名を読むことは、問題発生時の調査ガイドマップとしても機能する。例えば、「lab07_http_requests_total」というメトリクスは、HTTPリクエストの総数をメソッド、ルート、ステータスクラス別に記録していることがわかる。「lab07_dependency_duration_seconds」は、依存関係ごとの処理時間をコンポーネント、操作、結果別に記録している。これらのメトリクスが何を表しているかを理解しておくことで、異常を検知した際にどの情報を参照すれば良いかの見当がつく。
さらに、現代のシステムは複数のサービスがネットワークを介して連携する分散システムが主流だ。そのため、サービス間のHTTP通信を跨いでトレース情報を伝達させることは不可欠となる。OpenTelemetryのような標準的なプロトコルとライブラリを使用することで、あるサービスからのHTTPリクエストに含まれるトレースコンテキストを次のサービスが受け取り、そこでさらに処理を続けることができる。これにより、サービス境界を越えても一つのリクエストの全経路を追跡することが可能になり、マイクロサービスアーキテクチャのような複雑なシステムでの問題特定能力が大きく向上する。
オブザーバビリティの有効性を確認するためには、意図的に様々な障害シナリオを発生させてテストすることが重要だ。記事では、PDF生成が遅延するシナリオ、データベースアクセスが遅延するシナリオ、PDF生成が失敗するシナリオなどが挙げられている。これらのシナリオを再現し、その結果生成されるログ、メトリクス、トレースを分析することで、期待通りにシステムの内部状態が可視化され、問題の原因が特定できるかを検証する。これは、テレメトリデータが「契約」として機能しているか、つまり、期待通りの情報が、期待通りの形式で出力され、問題解決に役立つかどうかを確認する作業に他ならない。
まとめると、オブザーバビリティとは、単にシステムが動いているかを見るだけでなく、リクエストが内部でどのように処理され、どこで時間がかかり、なぜ失敗したのかを「システム自身に説明させる」能力のことだ。構造化ログ、集計メトリクス、そして因果関係を追跡するトレースという三つの柱を組み合わせることで、システムエンジニアは、たとえ複雑なシステムであっても、その内部で何が起こっているかを深く理解し、迅速に問題を解決できるようになる。