Observability入門

重要なオブザーバビリティに関する概念

オブザーバビリティとは何か

オブザーバビリティは、システムの内部構造を知らなくても、そのシステムについて質問することで、システムを外側から理解することを可能にします。 さらに、真新しい問題、つまり「未知の未知」のトラブルシューティングや対処が容易になります。 また、「なぜこのようなことが起こるのか」という疑問に答えるのにも役立ちます。

システムに関してこれらの質問をするためには、アプリケーションが適切に計装されていなければなりません。 つまり、アプリケーションのコードは、トレースメトリクスログなどのシグナルを発しなければなりません。 開発者が問題をトラブルシュートするために計装を追加する必要がないとき、アプリケーションは適切に計装されていると言えます。 なぜなら開発者が必要な情報をすべて持っているということになるからです。

OpenTelemetryは、システムをオブザーバビリティがある状態にするために、アプリケーションコードの計装を手助けする仕組みです。

信頼性とメトリクス

テレメトリー とは、システムやその動作から送出されるデータのことです。 データはトレースメトリクスログなどの形式で得られます。

信頼性 は「サービスがユーザーの期待通りに動いているでしょうか」といった疑問に答えてくれます。 システムは常に100%稼働していても、ユーザーがショッピングカートに黒い靴を追加するために「カートに追加」をクリックしたときに、システムが常に黒い靴を追加するとは限らない場合、システムは 信頼性がない と言えるでしょう。

メトリクス とは、インフラやアプリケーションに関する数値データを一定期間にわたって集計したものです。 たとえば、システムエラー率、CPU使用率、あるサービスのリクエスト率などです。 メトリクスとOpenTelemetryとの関係については、メトリクス のページを参照してください。

SLI(サービスレベル指標)は、サービスの動作の計測値を表します。 優れたSLIは、ユーザーの視点からサービスを計測します。 SLIの例として、ウェブページの読み込み速度が挙げられます。

SLO(サービスレベル目標)は、信頼性を組織や他のチームに伝達する手段を表します。 これは、1つ以上のSLIをビジネス価値に付加することで達成されます。

分散トレースを理解する

分散トレースにより、複雑な分散システムを通してリクエストが伝搬する様子を観察できます。 分散トレースはアプリケーションやシステムの健全性の可視性を向上させ、ローカルで再現するのが困難な挙動をデバッグできます。 これは、一般的に非決定論的な問題があったり、ローカルで再現するには複雑すぎる分散システムには不可欠です。

分散トレースを理解するには、ログ、スパン、トレースといった各要素の役割を理解する必要があります。

ログ

ログは、サービスや他のコンポーネントが発するタイムスタンプ付きのメッセージです。 トレースとは異なり、ログは必ずしも特定のユーザーリクエストやトランザクションに関連付けられているわけではありません。 ログは、ソフトウェアのあらゆる場所で見られます。 ログは、開発者と運用者の両方がシステムの挙動を理解するのに役立つため、これまで大いに利用されてきました。

次にあるのはログの例です。

I, [2021-02-23T13:26:23.505892 #22473]  INFO -- : [6459ffe1-ea53-4044-aaa3-bf902868f730] Started GET "/" for ::1 at 2021-02-23 13:26:23 -0800

ログはコードの実行を追跡するには十分ではありません。 ログには通常、どこから呼び出されたかといったコンテキスト情報が欠けているからです。

ログは、スパンの一部として含まれるとき、あるいはトレースやスパンと相関があるときに、はるかに有用になります。

ログの詳細とOpenTelemetryとの関係については、ログのページを参照してください。

スパン

スパン は作業または操作の単位を表します。 スパンは、リクエストが行う特定の操作を追跡し、その操作が実行された時間に何が起こったかを説明してくれます。

スパンには、名前、時間関連データ、構造化ログメッセージその他のメタデータ(つまり属性)が含まれ、追跡する操作に関する情報を提供します。

スパン属性

スパン属性はスパンに紐づけられたメタデータです。

次の表はスパン属性の例を列挙しています。

キー
http.request.method"GET"
network.protocol.version"1.1"
url.path"/webshop/articles/4"
url.query"?s=1"
server.address"example.com"
server.port8080
url.scheme"https"
http.route"/webshop/articles/:article_id"
http.response.status_code200
client.address"192.0.2.4"
client.socket.address"192.0.2.5" (クライアントはプロキシ経由)
user_agent.original"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"

スパンと OpenTelemetry との関係については、スパンの節を参照してください。

分散トレース

一般的にトレースとして知られている分散トレースは、マイクロサービスやサーバーレスアプリケーションのようなマルチサービスアーキテクチャを伝播するリクエスト(アプリケーションまたはエンドユーザーによって行われる)が辿った経路を記録します。

トレースは1つ以上のスパンで構成されるます。 最初のスパンはルートスパンを表します。 各ルートスパンは、リクエストの開始から終了までを表します。 親の下にあるスパンは、リクエスト中に発生すること(またはリクエストを構成するステップ)について、より詳細なコンテキストを提供します。

トレースなしでは、分散システムのパフォーマンス問題の根本的な原因を見つけることは困難です。 トレースは、分散システムを流れるリクエストの中で何が起こっているのかを分解することで、分散システムのデバッグと理解をしやすくします。

多くのオブザーバビリティバックエンドは、トレースをこのようなウォーターフォール図として視覚化しています。

トレースの例

ウォーターフォール図は、ルートスパンとその子スパンの親子関係を示しています。 スパンが別のスパンを含む場合も、入れ子関係を表します。

トレースとOpenTelemetryとの関係については、トレースのページを参照してください。