HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

必要なのは「ワイドイベント」だけで、「メトリクス、ログ、トレース」ではない

All you need is Wide Events, not "Metrics, Logs and Traces" (isburmistrov.substack.com)

40 pointsby bootlegbilly8 コメント

要約

この記事は、現代のオブザーバビリティ(可観測性)における混乱を指摘し、その原因としてOpenTelemetryの「メトリクス、ログ、トレース」という区分を挙げています。著者は、MetaのScubaシステムで使われていた「ワイドイベント」こそが、あらゆる情報を柔軟に記録・分析できる、よりシンプルで強力なオブザーバビリティの基盤であると主張しています。

全文翻訳

必要なのは「ワイドイベント」だけで、「メトリクス、ログ、トレース」ではない

[画像: Charity Majors氏のオブザーバビリティに関する引用画像]

Charity Majors氏のこの引用は、おそらくテクノロジー業界におけるオブザーバビリティの現状を最もよく要約しているでしょう――完全な、大規模な混乱です。誰もが混乱しています。トレースとは何ですか? スパンとは何ですか? ログ行はスパンですか? ログがあればトレースは必要ですか? 素晴らしいメトリクスがあればなぜトレースが必要なのですか? このような質問は尽きません。Charity氏――オブザーバビリティシステムであるHoneycombの他の素晴らしい人々とともに――これらの疑問に光を当てる素晴らしい仕事をしてきました。しかし、私の経験からすると、Charity氏が「ログはゴミだ」と言った意味を説明するのは依然として非常に困難であり、ログとトレースが本質的に同じものであるという事実を伝えるのはなおさらです。なぜ誰もがこれほど混乱しているのでしょうか?

少し辛口になるリスクを冒して、私はOpenTelemetryを非難します。はい、それは現代のオブザーバビリティスタックを支えていますが、それでも私はそれを大規模な混乱の元凶として非難します。それが悪いソリューションだからではなく――それは素晴らしいものです! しかし、OpenTelemetryとは何か、そしてそれが何をするのかを説明する際の提示方法とアプローチ全体が、オブザーバビリティをトリッキーで複雑に見せています。

まず、OpenTelemetryは最初からトレース、メトリクス、ログを明確に区別しています。

OpenTelemetryは、API、SDK、ツールのコレクションです。ソフトウェアのパフォーマンスと動作を分析するために、テレメトリデータ(メトリクス、ログ、トレース)をインストルメント化、生成、収集、エクスポートするために使用します。

次に、これら3つそれぞれについてさらに詳しく説明します。

[画像: OpenTelemetryのウェブサイトにおけるトレースの説明画像]

これはOpenTelemetryウェブサイトのトレースを紹介する部分からのスクリーンショットです。OpenTelemetryを扱う人々と話した私の経験に基づくと、この提示方法が確かにオブザーバビリティと関連付けられる主要なイメージの一つとなっています。一部の人々にとっては、これがオブザーバビリティそのものです。そしてそれはトレースを他のものから際立たせています。これは明らかにログではない、そうでしょう? メトリクスとも違って見えますよね? それは何か特別なもので、おそらく少し神聖なものであり、学習への投資を必要とします。私の経験では、人々がトレースについて学んだ後、彼らはそれをこの画像と、スパン、ルートスパン、ネストされたスパンといった用語のセットの文脈でしか考えなくなります。OpenTelemetryサイトには60以上の用語がある用語集ページがあります! これらすべてが信じられないほど複雑です!

しかし、より重要なのは――この「ログ、メトリクス、トレース」への焦点は、オブザーバビリティの真の力を表しているのでしょうか? それがいくつかのシナリオをカバーしているのは事実ですが、分散システムが大規模になると、より重要なのはデータに「掘り下げる」能力――それを「スライス&ダイス」する能力、さまざまなビューを構築・分析する能力、相関関係を調べる、異常を検索する……といったことです。そして、これらすべてを提供するシステムは存在します。

Scuba: オブザーバビリティの楽園

Metaで働いていたとき、私は史上最高のオブザーバビリティシステムを使っていたという特権に気づいていませんでした。このシステムはScubaと呼ばれ、人々がMetaを離れるときに最も惜しむものトップ1です。

Scubaの基本的なアイデアは非常にシンプルで、人々が理解するために用語集ページを必要としません。それはワイドイベントを扱います。ワイドイベントは、名前と値のフィールドのコレクションにすぎず、JSONドキュメントに非常に似ています。システムの状態、またはAPI呼び出し、バックグラウンドジョブなどによって引き起こされたイベントに関する情報を記録する必要がある場合は、Scubaにワイドイベントを書き込むだけです。例えば、システムが広告を提供している場合、自然な欲求は広告インプレッションを記録することでしょう――特定の広告がユーザーによって表示されたという事実です。対応するワイドイベントは次のようになるかもしれません。

{
    "Timestamp": "1707951423",
    "AdId": "542508c92f6f47c2916691d6e8551279”,
    "UserCountry": "US",
    "Placement": "mobile_feed",
    "CampaingType": "direct_ads",
    "UserOS": "Android",
    "OSVersion": "14",
    "AppVersion": "798de3c28b074df9a24a479ce98302b6",
    ...
}

このようなイベントはワイドと呼ばれます。なぜなら、考えられるすべての情報をそれにダンプすることが奨励されているからです。あるデータに関連する可能性のあるものは何でも――それに含めてください。後で役立つかもしれません。このアプローチは、「未知の未知」に対処するための基盤を築きます――現在考えられないが、インシデント調査中に後で明らかになる可能性のあるものです。

未知の未知に対処することは、例でよりよく示すことができます。Scubaには、探索して操作するのが簡単な、直感的で優れたインターフェースがあります。そこでメトリクスを選択できるセクション、フィルターとグループ化のセクションがあり――Scubaは素晴らしい時系列チャートを描画します。まず広告インプレッションデータセットを探すと、単純にインプレッション数のチャートが表示されます。

[画像: Scubaの広告インプレッションの基本的な時系列チャート画像]

ここで正確に何が選択されているかをSQLで表現すると、次のようになります。

SELECT COUNT(*) FROM AdImpressions
WHERE IsTest = False

まあ、実際には正確にはそうではありません。Scubaにはネイティブサンプリングの概念もあります。特定のイベントがScubaに書き込まれるとき、samplingRateというフィールドも書き込む必要があります――その特定のイベントがサンプリングされているレートです。Scubaはこの情報を使用して、チャートに表示される結果を適切に「アップスケール」します。そのため、頭の中でこのアップスケールを行う必要はありません。これは本当に素晴らしい概念です。なぜなら、動的なサンプリングを可能にするからです――例えば、あるタイプのインプレッションは他のタイプよりも多くサンプリングされるかもしれませんが、UIでの「実際の」値を維持します。したがって、実際のクエリは次のようになります。

SELECT SUM(samplingRate) FROM AdImpressions
WHERE IsTest = False

この「アップスケール」全体がUIによって透過的に行われ、ユーザーはクエリ中にそれを考えないことに注意してください。

そして、アラートが発生し、私たちの貴重な広告インプレッションチャートがおかしくなっていることを示していると仮定します。

[画像: Scubaで異常な広告インプレッションチャートが表示されている画像]

Scubaを使って調査する誰もが最初に取るべき行動は、「スライス&ダイス」、つまりフィルターまたはグループ化して、何かを学べるかどうかを確認することです。私たちは何を探しているのか分かりませんが、それを見つけられると信じています。そこで、例えばインプレッションタイプ、ユーザーの国、または配置でグループ化し、何か疑わしいものを見つけるまで続けます。キャンペーンタイプでグループ化してみましょう。

[画像: Scubaでキャンペーンタイプでグループ化された広告インプレッションの異常画像]

in_app_purchasesというキャンペーンタイプ(念のため、このタイプ名は私が完全に作成したものであることを指摘しておきます)が、他のものとは異なって見えることがわかります。それが何を意味するのかは本当には分かりません――続けるために、それを知る必要はありません! OK、これでこれらのキャンペーンのみをフィルターし、他に考えられるものでグループ化を続けることができます。例えば、ユーザーOSは理にかなっています。

[画像: ScubaでキャンペーンタイプとユーザーOSでグループ化された広告インプレッションの異常画像]

うーん、Androidが問題を抱えているようです。iOSはOKです。これは問題がクライアント側にあることを示唆しています――壊れたアプリバージョンかもしれませんか?

[画像: Scubaでキャンペーンタイプ、ユーザーOS、OSバージョンでグループ化された広告インプレッションの異常画像]

奇妙です。一部のバージョンは苦しんでいますが、他のバージョンはそうではありません。OSバージョンを確認してみましょうか?

[画像: Scubaでキャンペーンタイプ、ユーザーOS、OSバージョン、アプリバージョンでグループ化された広告インプレッションの異常画像]

ハッ! 最新バージョンのOSであり、一部のアプリバージョンがこのOSバージョンでこのタイプのキャンペーンでうまく機能していないようです。この情報があれば、担当チームはさらに深く調査できるでしょう。

何が起こったのでしょうか? システムについて何も知らなくても、問題の範囲を絞り込み、さらなる調査を主導するチームを特定しました。このOS、OSバージョン、キャンペーンタイプ、アプリバージョンの奇妙な組み合わせが問題を引き起こす可能性があり、専用のメトリクスを用意しておけばよかったと事前に知ることができたでしょうか? もちろんできません。これは未知の未知に対処する例です。関連するコンテキストすべてをワイドイベントにドロップし、後で必要になったときに使用しました。Scubaは、それが高速で非常に使いやすいUIを備えているため、探索を簡単に行えるようにしました。また、カーディナリティ(値の種類の数)については何も言及していないことにも注意してください。なぜなら、それは問題ではないからです――どのフィールドも任意のカーディナリティを持つことができます。Scubaは生のイベントを扱い、何も事前集計しないため、カーディナリティは問題になりません。

UI/可視化の側面は十分に注目されないことがあり、オブザーバビリティシステムはクエリ言語を提供します――独自の言語(悪い、悪い、悪い)か、SQL(少し良いが、まだ悪い)のいずれかです。そのようなインターフェースでは、同様の調査を実行することはほぼ不可能です。Scubaの重要な側面は、関数、フィルター、グループ化などのすべてのフィールドが探索可能であるということです。つまり、選択できる値の種類を簡単に確認できる方法があるということです。特定のフィールドの所有者が怠惰でない場合、彼らは関連リンクなどを含むフィールドの詳細な説明さえ含んでいます。これは巨大です。私はシステム全体やこのデータセットで利用可能なデータについて完全に理解していなくても、自分で多くのインシデントを調査することに成功しました。そして、Scubaで遊ぶだけで、調査中にシステムについて多くを学びました! これは驚くべきことでした。これはオブザーバビリティの楽園でした。

Meta後の悲惨さ

Metaを離れて、外部のオブザーバビリティシステムの状況を知ったときの私の混乱と不信感を想像してみてください。

[画像: 混乱した表情の人物の画像]

ログ? トレース? メトリクス? 一体何? ワイドイベントは? 用語集から60の用語を学ぶのをやめて、ただ……何かを探索することはできませんか?

ScubaベースのメンタルモデルをOpenTelemetryのメンタルモデルにマッピングするのにかなりの時間がかかりました。OpenTelemetryのSpanは、実際にはワイドイベントであると認識しました。実際、まだ完全に理解しているか確信が持てません。

[画像: OpenTelemetryのSpanとMetaのワイドイベントの比較画像]

AdImpressionの例を取ると、このインプレッションは実際には操作ではなく、記録したい単なる事実です……公平を期すために言うと、OpenTelemetryにはEventという概念があります。

[画像: OpenTelemetryのEventに関する説明画像]

しかし、リンクをたどってさらに深く掘り下げると、Eventは実際にはトレース、メトリクス、またはログのいずれかであることがわかります🤷

[画像: OpenTelemetryのEventがトレース、メトリクス、ログのいずれかであることを示す画像]

しかし、とにかく、Spanはワイドイベントに最も近い概念です。問題は――OpenTelemetryが提案するメンタルモデルがすでに学習されている場合、このメンタルモデルを提唱するのは非常に難しいということです。これは本当に残念なことです。なぜなら、トレース、メトリクス、ログはすべてワイドイベントの特別なケースにすぎないからです。

  • トレースとスパン: これらは、SpanId、TraceId、ParentSpanIdフィールドを持つワイドイベントにすぎません。したがって、指定されたTraceIdを持つすべてのスパンをフィルターし、SpanId → ParentSpanId関係を使用してそれらをトポロジカルにソートし、誰もが愛する分散トレーシングビューを描画できます。

  • ログ: 正直なところ、OpenTelemetryがログで何を意味するのか混乱しています。それは多くのことのように見えますが、そのうちの1つは構造化ログであり、これはワイドイベントに非常に似ています。素晴らしい! しかし、問題は、「ログ」はかなり定義された概念であり、通常人々がそれを意味するのはlogger.info(...)呼び出しによって生成されるものです。とにかく、何であれ、ログは当然ワイドイベントに簡単にマッピングできます。最も単純なケースでは、ログメッセージを取得し、「log_message」フィールドに入れ、メタデータをたくさん追加して満足できます。より複雑なケースでは、IDのように見えるトークンを削除してログメッセージからテンプレートを自動的に抽出しようとすることができます。これにより、例えばグループ化によって最も頻繁なエラーをすばやく取得できます。Metaにはそのようなシステムがあり、それは非常にクールです。

  • メトリクス: メトリクスも簡単にマッピングできます。システムの現在の状態(CPUのようなシステムメトリクス、さまざまなカウンターなど)を含む一定の間隔ごとに1回ワイドイベントを発行するだけで済みます。ちなみにPrometheusは、スクレイピングアプローチでまさにこれを行います――時々システムのスナップショットを取得します。ただし、Prometheusとは異なり、ワイドイベントアプローチではカーディナリティを気にする必要はありません。

しかし、ワイドイベントはこれら「3つの柱」よりもはるかに多くのものを提供できます。前述のデバッグセッションは、トレース、ログ、メトリクスでは――少なくとも自然には――カバーされていないケースです。他のユースケースも考えられます――例えば、継続的なプロファイリングデータをワイドイベントとして簡単に表現し、Flame Graphを構築するためにクエリすることができます。これのために別のシステムを持つ必要はありません――ワイドイベントを扱う単一のシステムですべてを行うことができます。すべてが一箇所にあり、一緒に保存されている場合のクロス相関と根本原因分析の可能性を想像してみてください。特に、データ内の相関関係を見つけるのに非常に優れたAIベースのツールの台頭の時代においては。

そして、どうなる?

分かりません……ただ、混乱のレベルと「3つの柱」へのこの焦点に対する私の不満を表現したかっただけです。

オブザーバビリティベンダーが混乱に対して立場を取り、システムと対話するためのシンプルで自然な方法を提供してくれることを願っています。Honeycombはそうしているようですし、Axiomのような他のシステムもそうです。それは素晴らしいことです! そして、他の人々もそれに続くことを願っています。