OTEP-0174: HTTPのトレーシング用セマンティック規約に関するシナリオと未解決の課題
本文書は、シナリオ・未解決の課題とロードマップをまとめることを目的としており、これらは現在実験的な状態にある既存のHTTP向けセマンティック規約を安定化するための基盤となります。 目標は、2022年第1四半期の終わりまでにHTTPセマンティック規約を安定版として宣言することです。
動機
ほとんどのオブザーバビリティのシナリオはHTTP通信を伴います。 シナリオ全体を通じて分散トレーシングを有用なものにするには、HTTPに対する優れたオブザーバビリティが不可欠です。 これを実現するために、OpenTelemetryはHTTP通信の計装のための安定した規約とガイドラインを提供しなければなりません。
既存の実験的なHTTP向けセマンティック規約を安定した状態にすることは、ユーザーと計装の作者にとって重要なステップです。 なぜなら、これにより安定性の保証に頼ることができるようになり、安定した計装を出荷し利用できるようになるからです。
[!NOTE] 本OTEPは、既存の実験的なHTTP向けセマンティック規約に対して行うべき変更のスコープを記録するものであり、解決策を提案するものではありません。
v1.0に向けたロードマップ
- シナリオ/未解決の課題と提案されたロードマップからなる本OTEPが承認され、マージされます。
- セマンティック規約に対する安定性の保証が承認され、マージされます。 これはHTTP向けセマンティック規約に厳密に関係するものではありませんが、あらゆるセマンティック規約を安定化するための前提条件です。
- 本文書に記載されているシナリオと未解決の課題に対応する個別のPRが承認され、マージされます。
- 提案された仕様変更が、以下のシナリオと例に対するプロトタイプによって検証されます。
- HTTP向けトレーシングセマンティック規約の仕様が本OTEPに従って更新され、安定であると宣言されます。
ロードマップのステップは必ずしも記載された順序で行われる必要はなく、いくつかのステップは並行して進めることができます。
v1.0のスコープ: シナリオと未解決の課題
[!NOTE] ここで定義されているスコープは議論の対象であり、本OTEPがマージされるまでの間に調整される可能性があります。
以下に挙げるシナリオと未解決の課題は、個別のPRで対応する必要があります。
エラーステータスのデフォルト
SpanKind.SERVER の場合、4xxレスポンスはもはやエラーステータスコードを生成しません。
SpanKind.CLIENT に対しても同様/類似の振る舞いを定義することが妥当だと考えられます。
必須の属性セット
以下の属性セットのうち、少なくとも1つが必要です。
http.urlhttp.scheme、http.host、http.targethttp.scheme、net.peer.name、net.peer.port、http.targethttp.scheme、net.peer.ip、net.peer.port、http.target
その結果、生データやZipkin/Jaegerに対してクエリを書くユーザーは、計装や言語をまたいで一貫したストーリーを得られません。
たとえば、select * where (getPath(http.url) == "/a/b" || getPath(http.target) == "/a/b") のようなクエリを書く必要が生じます。
関連するissue: open-telemetry/opentelemetry-specification#2114
リトライとリダイレクト
各試行/リダイレクトのリクエストは、トレース可能にし、下流のサービスに対して曖昧さなくサポートを求められるようにするために、一意なコンテキストを持つべきでしょうか(これはコールごとのスパンを意味します)。
リダイレクト: ユーザーは、どのサーバーホップでエラーが発生したか、あるいは時間がかかりすぎたかについてのオブザーバビリティを必要とする場合があります。 たとえば、500エラーやタイムアウトは最終的な宛先で発生したものか、それともプロキシで発生したものかといった点です。
関連するissue: open-telemetry/opentelemetry-specification#1747、open-telemetry/opentelemetry-specification#729
このシナリオに対応するPR: open-telemetry/opentelemetry-specification#2078
コンテキストの伝播
試行間でコンテキストをどのように伝播させるべきでしょうか。 クライアントのHTTPリクエストのインスタンスを再利用する場合、コールを行う前にコンテキストをクリーンアップすべきでしょうか。
vNextのスコープ: シナリオと未解決の課題
エラーステータスの設定
多くの場合、4xxのエラー基準はアプリケーションに依存します(たとえば404や409の場合)。 エンドユーザーとしては、既存のデフォルトを上書きし、どのHTTPステータスコードをエラーとみなすかを定義できる機能が欲しいかもしれません。
オプション属性
ライブラリのオーナーとしては、オプション属性の利点が理解できません。 オプション属性はオーバーヘッドを生み、汎用的に有用であるようには見えず(たとえば flavor)、統一しない限り言語やライブラリ間で一貫性がありません。
関連するissue: open-telemetry/opentelemetry-specification#2114
セキュリティ上の懸念
一部の属性には、機密性のある情報が含まれる可能性があります。
おそらく、デフォルトではWebフレームワークやHTTPクライアントはこれらを公開すべきではありません。
たとえば、http.target にはクレデンシャルを含む可能性のあるクエリ文字列が含まれます。
[!NOTE] セキュリティ上の懸念をv1.0から意図的に除外したわけではなく、単にこれまで十分に検討できていないだけです。
noopケースにおけるサンプリング
noopケースを効率化するために、事前サンプリング属性を作成する前に、SDKが存在し設定されていることを計装に伝えるヒント(たとえば GlobalOTel.isEnabled())を用意しておくと有用かもしれません。
ロングポーリングとストリーミング
これらのシナリオに固有の考慮事項はあるでしょうか。 たとえば、スパンの継続時間やステータスコードの観点からはどうでしょうか。 同一の論理セッション内にある複数のリクエストをどのようにモデル化すべきでしょうか。
HTTP/2、gRPC、WebSockets
ここでもっとうまくやれることはあるでしょうか。 多くの場合、コネクションはアプリケーションのライフタイムを持ち、メッセージは独立していますが、個々のメッセージに対する手動トレーシングの方法をユーザーに説明できるでしょうか。 メッセージごとのスパンイベントはそもそも意味があるのでしょうか。 ここには実際の経験や専門知識が必要です。
リクエスト/レスポンスボディのキャプチャ
[!NOTE] これは技術的にはスコープ外ですが、ユーザーがこれを行えるようにする方法についての考えは持っておくべきです。
これを求めるユーザーからのフィードバックは数多くありますが、次のような課題があります。
- 汎用的な計装ではボディを読み取ることができません
- ユーザー自身にボディを収集させることはできます
- サーバースパンへのアタッチは容易です
- クライアント向けの仕様: ユーザーがボディをHTTPクライアントスパンと曖昧さなく関連付けられるアプローチが必要です(たとえば、HTTP呼び出しとレスポンスの読み取りをラップし、ボディを含むイベント/ログを持つ外側の手動スパン)
- ボディの読み書きはHTTPクライアントAPIの外部(たとえばネットワークストリーム経由)で発生することがあります。 この場合、ユーザーはどのように追跡できるでしょうか。
関連するissue: open-telemetry/semantic-conventions#1219
スコープ外
HTTPプロトコルは、さまざまな異なるプラットフォームやシステムの中で広く使用されており、伝送プロトコル層とアプリケーション層との間に多くの交差点を生み出しています。 しかし、HTTPセマンティック規約の仕様に関しては、仕様を明確に保つために、分散トレーシングにおけるHTTP固有の側面に厳密に焦点を当てたいと考えています。 したがって、以下のシナリオは、これに限定されるものではありませんが、本ワーキンググループのスコープ外とみなされます。
- バッチ操作
- ファンインおよびファンアウト操作(たとえばGraphQL)
- ヘッジングポリシー。 ヘッジングは、レスポンスを待たずに単一のリクエストの複数のコピーを積極的に送信することを可能にします。 ヘッジされたRPCは、通常は異なるバックエンドによって、サーバー側で複数回実行される場合があります。
- 他のシステムのためのトランスポート層としてのHTTP(たとえば、HTTP上に構築されたメッセージングシステム)
これらのシナリオに対応するために、今後OpenTelemetryコミュニティと協力して計装ガイドラインを構築していきたいと考えています。
OpenTelemetry全般の未解決の課題
現在、いくつかのOpenTelemetry全般に関わる未解決の課題が存在しており、これらは上記のシナリオと未解決の課題への対応方法におそらく影響を与えるでしょう。
- 特定のデフォルトを上書きするための設定言語はどのようなものになるか。 たとえば、どのHTTPステータスコードをエラーとみなすか。
- リトライやリダイレクトのような、スパンに対する追加の詳細レベルをどのように扱うか。 そもそも、これは詳細レベルとして設計すべきなのか、それとも論理的または物理的な相互作用/トランザクションを反映するレイヤーとして設計すべきなのか。
- リンクのデータモデルはどのようなものか。 妥当なストレージの実装はどのようなものになるか。