> Source: https://www.ymotongpoo.com/works/oteps/trace/otep-0205/


# OTEP-0205: メッセージングセマンティック規約のためのコンテキスト伝搬要件

[トレーシングのための既存のメッセージングセマンティック規約](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/messaging.md)は、使用されるコンテキスト伝搬メカニズムに対して暗黙のうちに一定の要件を課しています。
本文書は、この要件を明示的にする方法を提案します。

このOTEPは[OTEP 0173](0173-messaging-semantic-conventions.md)を基にしており、OTEP 0173ではメッセージングセマンティック規約でサポートされるべき基本用語とメッセージングシナリオを定義しています。

* [用語](#terminology)
* [動機](#motivation)
  * [例](#example)
* [メッセージングセマンティック規約への追加提案](#proposed-addition-to-the-messaging-semantic-conventions)
  * [コンテキスト伝搬](#context-propagation)
  * [要件](#requirements)
* [今後の可能性](#future-possibilities)
  * [トランスポートコンテキストの伝搬](#transport-context-propagation)
  * [コンテキスト伝搬の標準](#standards-for-context-propagation)

## 用語 {#terminology}

本文書で使用される用語については、[OTEP 173](0173-messaging-semantic-conventions.md#terminology)を参照してください。

## 動機 {#motivation}

現在の[トレーシングのためのメッセージングセマンティック規約](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/messaging.md)は、[例](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.11.0/specification/trace/semantic_conventions/messaging.md#examples)の一覧を提供しています。
それらの例は、プロデューサースパンとコンシューマースパンが親子関係またはリンクによってどのように相関付けられるかを示しています。
すべての例は、あるメッセージに対するコンテキスト情報がプロデューサーからコンシューマーへ伝搬されることを前提としています。

しかし、これは自明な前提ではなく、既存の確立されたコンテキスト伝搬メカニズムでは容易には対応できません。
それらのメカニズムはリクエスト単位でコンテキストを伝搬しますが、メッセージングセマンティック規約はコンテキストがメッセージ単位で伝搬されることを前提としています。
つまり、1つのメッセージの処理には複数のリクエストが関与しうる（メッセージの発行、メッセージの取得、場合によっては複数のコンシューマーによる複数回の取得）にもかかわらず、すべてのコンポーネントがメッセージの処理のすべての段階を相関付けられる、同一のメッセージ単位のコンテキスト情報にアクセスできることが前提とされています。

この望ましい結果を達成するには、コンテキストをメッセージに添付する必要があり、また仲介者はメッセージに添付されたコンテキストを変更してはなりません（must not）。
_この要件は文書化されるべきです。
なぜなら、これはメッセージシナリオに対するコンテキスト伝搬の方法や、既存のメッセージプロトコルに対するコンテキスト伝搬の標準化の方法を決定する上での重要な要因だからです。_

本文書で提案する追加は、メッセージングに関する既存のセマンティック規約のいずれも破壊したり無効にしたりするものではなく、むしろ暗黙の要件を明示的にするものです。

### 例 {#example}

多くの仲介者（メッセージブローカー）は、メッセージの発行と取得のためのREST APIを提供しています。
プロデューサーは仲介者にHTTPリクエストを送信することでメッセージを発行でき、コンシューマーは仲介者にHTTPリクエストを送信することでメッセージを取得（プル）できます。

```
  +----------+
  | Producer |
  +----------+
       |
       | HTTP POST (publishing a message)
       v
+--------------+
| Intermediary |
+--------------+
       ^
       | HTTP GET (fetching a message)
       |
  +----------+
  | Consumer |
  +----------+
```

既存のセマンティック規約は、コンシューマーがプロデューサーのトレースからのコンテキスト情報を使って、コンシューマーとプロデューサーのトレース間にリンクや親子関係を作成できることを前提としています。
これが可能であるためには、プロデューサーのコンテキスト情報がコンシューマーに伝搬される必要があります。
上記の例では、コンシューマーはメッセージを取得するために仲介者へHTTP GETリクエストを送信し、そのレスポンスの一部としてメッセージが返されます。
このHTTPリクエストを通じて、コンテキスト情報はコンシューマーから仲介者へ伝搬できますが、仲介者からコンシューマーへは伝搬できません。
コンシューマーは、必要なプロデューサーのコンテキスト情報が、メッセージの発行や取得のためのHTTPコンテキスト伝搬とは独立に、メッセージ自体の一部として伝搬されている場合にのみ、それを取得できます。

特別な仲介者の計装なしにプロデューサーとコンシューマーのトレースを相関付けるためには、プロデューサーのコンテキストをメッセージに添付し、メッセージの発行と取得のためのHTTPリクエストで伝搬されるコンテキストとは関係なく、コンシューマーがそれを抽出して使用できるようにすることが必要です。

OpenTelemetryのセマンティック規約は、あらゆる仲介者やあらゆるプロトコルに対してこれを実現するための正確なメカニズムを規定することはできませんが、この要件はプロトコルや計装によって実装できるように明確に定式化されなければなりません（must）。

## メッセージングセマンティック規約への追加提案 {#proposed-addition-to-the-messaging-semantic-conventions}

### コンテキスト伝搬 {#context-propagation}

メッセージがプロデューサーからコンシューマーへ伝搬される際、1つまたは複数の仲介者において多くの異なるコンポーネントやレイヤーを通過することがあります。
それらすべてのコンポーネントやレイヤーが計装されており、OpenTelemetryの要件に従ってコンテキストを伝搬しているとは想定できませんし、多くの場合、それは望まれてもいません。

_メッセージ作成コンテキスト_ は、仲介者の計装の有無にかかわらず、プロデューサーとメッセージのコンシューマーを相関付けることを可能にします。
メッセージ作成コンテキストはプロデューサーによって作成され、コンシューマーに伝搬されるべきです（should）。
これは仲介者によって変更されるべきではありません（should not）。
このコンテキストは、基盤となるメッセージングトランスポートメカニズムやその計装にかかわらず、プロデューサーとコンシューマーの間の依存関係をモデル化するのに役立ちます。

計装作成者は、コンテキストがメッセージに添付され、協調した方法でメッセージから抽出されるように、プロデューサーアプリケーションとコンシューマーアプリケーションを計装することが求められます（required）。
これらの規約の将来のバージョンでは、[特定の業界標準に従ったコンテキスト伝搬](#standards-for-context-propagation)が推奨されるかもしれません。
メッセージ作成コンテキストをメッセージに添付して伝搬できない場合、コンシューマーのトレースをプロデューサーのトレースに直接相関付けることはできません。

### 要件 {#requirements}

プロデューサーは、各メッセージにメッセージ作成コンテキストを添付するべきです（SHOULD）。
メッセージ作成コンテキストは、仲介者によって変更されることができないような方法で添付されるべきです（SHOULD）。

## 今後の可能性 {#future-possibilities}

### トランスポートコンテキストの伝搬 {#transport-context-propagation}

メッセージ作成コンテキストはメッセージに添付できる一方で、メッセージの発行と取得のリクエストとともに異なるコンテキストが伝搬されることもあります。
仲介者の計装に関する規約やガイダンスを策定する際には、これら2つのコンテキスト伝搬のレイヤーを明確に区別し、その区別の上に仲介者の計装のための規約を構築することが有益です。

1. _メッセージコンテキストレイヤー_ は、仲介者の計装の有無にかかわらず、プロデューサーとメッセージのコンシューマーを相関付けることを可能にします。
   作成コンテキストはプロデューサーによって作成され、コンシューマーに伝搬されなければなりません（must）。
   これは仲介者によって変更されてはなりません（must not）。

   このレイヤーは、基盤となるメッセージングトランスポートメカニズムやその計装にかかわらず、プロデューサーとコンシューマーの間の依存関係をモデル化するのに役立ちます。
2. 追加の _トランスポートコンテキストレイヤー_ は、プロデューサーおよびコンシューマーを仲介者と相関付けることを可能にします。
   また、複数の仲介者どうしの相関付けも可能にします。
   トランスポートコンテキストは、仲介者の計装に応じて仲介者によって変更されることがあります。

   このレイヤーは、メッセージトランスポートの詳細に対する洞察を得るのに役立ちます。

これにより、プロデューサーとコンシューマーの間の既存の相関関係を維持しながら、仲介者がトランスポートコンテキストを使って、仲介者の計装を既存のプロデューサーおよびコンシューマーの計装と相関付けられるようになります。

### コンテキスト伝搬の標準 {#standards-for-context-propagation}

現在のところ、計装の作成者は[コンテキスト伝搬の要件](#context-propagation)を満たすために、メッセージからどのようにコンテキストを添付・抽出するかを自分で決める必要があります。
計装の作成者がコンテキストをどのように伝搬するかを選択する自由を維持しつつ、将来的にはこれらの規約は、十分に確立されたメッセージングプロトコルを使ってコンテキストを伝搬する推奨方法を列挙するべきです。

さまざまなメッセージングプロトコルやシナリオに対するコンテキスト伝搬を標準化するための、進行中の取り組みがいくつか存在します。

* [AMQP](https://w3c.github.io/trace-context-amqp/)
* [MQTT](https://w3c.github.io/trace-context-mqtt/)
* [CloudEvents via HTTP](https://github.com/cloudevents/spec/blob/v1.0.1/extensions/distributed-tracing.md)

これらの標準が安定した状態に達し、メッセージ作成コンテキストとトランスポートコンテキストの表現方法を定義した時点で、これらのセマンティック規約は各プロトコルおよびシナリオに対する明確で安定した推奨事項を示すことになります。

