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


# OTEP-0136: ステータスコードによるエラーフラグ付け

この提案は、ステータスコードの数を3つに減らし、アプリケーション開発者とオペレーターによって設定されたステータスコードを識別するための新しいフィールドを追加し、セマンティック規約からステータスコードへのマッピングを追加します。
これにより、OpenTelemetryにおけるエラー報告の仕組みが明確になります。

注: 本文書における **エンドユーザー** という用語は、OpenTelemetryを実行するシステムのアプリケーション開発者およびオペレーターと定義されます。
**計装** という用語は、Webフレームワークやデータベースクライアントなど、異なるシステム間で共有される共通コードのための[計装ライブラリ](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library)を指します。

## 動機 {#motivation}

エラー報告は、分散トレーシングにおける基本的なユースケースです。
私たちはエラーフラグ付けが計装内ではなく分析ツール内で行われることを望んでいますが、現在サポートされている多くの分析ツールやプロトコルは、計装から報告される明示的なエラーフラグの存在に依存しています。
OpenTelemetryでは、このエラーフラグは「ステータスコード」と呼ばれています。

しかし、セマンティック規約からステータスコードへのマッピングには混乱があり、エラーの主観的な性質についても懸念があります。
どのネットワーク障害がエラーとしてカウントされるのでしょうか。
404はエラーでしょうか。
その答えは状況によって異なることが多いですが、各規約に対する推奨ステータスコードの基準すらなければ、計装の作者は重い決断の負担を負わされることになります。
さらに悪いことに、その決断は異なる計装間で一致しないでしょう。

適切なエラーフラグ付けに必要な、もう一つの欠けているピースがあります。
アプリケーション開発者とオペレーターの両方は、自分たちのシステムにおいて何がエラーを構成するかについて深い理解を持っています。
OpenTelemetryは、これらのユーザーがエラーフラグ付けを制御し、ステータスコードを設定しているのが計装ではなくエンドユーザーであることを明示的に示す方法を提供しなければなりません。
これらの特定のケースでは、エラーフラグ付けが正しいことがわかっています。
つまり、エンドユーザーがスパンのステータスを決定しており、彼らは別の解釈を望んでいないのです。

汎用的な計装は汎用的なスキーマしか提供できませんが、エンドユーザーは自分たちのシステムについて主観的な判断を下すことができます。
そして、エンドユーザーとして、彼らは何がエラーを構成するかについて最終的な決定権を持つべきです。
これを実現するには、計装によってフラグ付けされたエラーと、エンドユーザーによってフラグ付けされたエラーを区別する方法が必要です。

## 解説 {#explanation}

以下の変更は、適切なエラー報告に必要ないくつかの不足している機能を追加するものであり、現在のOpenTelemetryと完全に後方互換性があります。

### ステータスコード {#status-codes}

現在、OpenTelemetryには異なる種類のエラーを区別するユースケースがありません。
しかし、このユースケースは将来的に出現する可能性があります。
今のところ、私たちはステータスコードの数を減らし、必要性が明確になった時点で追加していきたいと考えています。
また、設定されていないステータスコードと、エンドユーザーによって明示的に設定された `OK` ステータスとを区別したいと考えています。

* `UNSET` はデフォルトのステータスコードです。
* `ERROR` はすべてのエラー種別を表します。
* `OK` は、明示的にエラーがないとマークされたスパンを表し、エラーバジェットに対してカウントされるべきではありません。
  このステータスはエンドユーザーのみが設定すべきであることに注意してください。
  代わりに、計装はエラーを生成しない操作に対してステータスを `UNSET` のままにすべきです（SHOULD）。

### `Status Source` {#status-source}

新しいStatus Sourceフィールドは、スパン上のステータスコードの発生源を識別します。
これは重要です。
なぜなら、アプリケーション開発者やオペレーターによって設定されたステータスは、その特定の状況に対して正しいとエンドユーザーによって確認されたものだからです。
一方、計装によって設定されたステータスは、汎用的なスキーマに従っているに過ぎません。

* `INSTRUMENTATION` はデフォルトのソースです。
  これは、OSSライブラリやフレームワークなど、共有コード内に含まれる計装に使用されます。
  OpenTelemetryに同梱されるすべての計装プラグインは、このステータスコードを使用します。
* `USER` は、アプリケーションコードまたはCollector内で、アプリケーション開発者またはオペレーターによって設定されたステータスを識別します。

分析ツールは独自のエラー分析アプローチを採用し、ステータスコードを無視してもかまいません（MAY）。
しかし、分析ツールは、それがアプリケーション開発者またはオペレーターからの伝達であり、貴重な情報を含んでいるため、`USER` によって設定されたステータスコードに注意を払うことが強く推奨されます（SHOULD）。

### ステータスマッピングスキーマ {#status-mapping-schema}

仕様の一部として、OpenTelemetryはセマンティック規約からステータスコードへのマッピングを提供します。
これにより、OpenTelemetryが標準で何を提供するかについての曖昧さがなくなります。

正しいステータスコードをセマンティック規約の一部として含めることで、データベースプロトコルのような言語横断的な概念に関連するエラーが発生した際に、私たちの計装の一貫性を確保するのに役立ちます。

セマンティック規約、およびそれに基づく規約からステータスへのマッピングは、まだ作業中であり、GA後も変更が続くことに注意してください。

### ステータスプロセッサー {#status-processor}

Collectorは、このステータスマッピングスキーマを調整するためのプロセッサーと設定言語を提供します。
これにより、実世界のシナリオに必要な柔軟性とカスタマイズが実現します。

### 便利な関数 {#convenience-methods}

便宜上、OpenTelemetryはセマンティック規約と例外をスパンに追加するためのヘルパー関数を提供します。
これらのヘルパー関数は、正しいステータスコードも設定します。
これにより、計装の作者の作業が簡素化され、準拠性とデータ品質の確保に役立ちます。

これらの便利な関数は、単に複数のAPI呼び出しを配線しているに過ぎないことに注意してください。
それらはヘルパーパッケージ内に置かれるべきであり、既存のAPIインターフェースに直接追加されるべきではありません（SHOULD NOT）。
私たちが持っているセマンティック規約の数を考えると、それらは山ほどの数になるでしょう。

## 内部の詳細 {#internal-details}

この提案は、既存のコード、プロトコル、およびOpenTracingブリッジとほぼ後方互換性があります。
唯一の潜在的な例外は、現在のOTLPプロトコルからのステータスコード列挙型の削除と、それらを利用していた少数の計装の書き換えです。

## BUT ERRORS ARE SUBJECTIVE!! HOW CAN WE KNOW WHAT IS AN ERROR? WHO ARE WE TO DEFINE THIS? {#but-errors-are-subjective-how-can-we-know-what-is-an-error-who-are-we-to-define-this}

まず第一に、これまでのすべてのトレーシングシステムには、デフォルトのエラーセットが付属しています。
エンドユーザーが完全に一から始めることを要求するシステムはありません。
ですから……落ち着いてください！信じてください！

エラーのフラグ付けは主観的な判断になり得ますが、多くのセマンティック規約がエラーとして認定されるのも事実です。
セマンティック規約からエラーへのデフォルトマッピングを提供することで、既存の分析ツール（Jaegerなど）との互換性を確保し、ユーザーと将来の実装者にガイダンスを提供します。

もちろん、すべてのシステムは異なっており、ユーザーはケースバイケースでエラー報告を調整したいと考えるでしょう。
不要なエラーは抑制することができ、追加のエラーを加えることもできます。
Collectorは、これを簡単なプロセスにするためのプロセッサーと設定言語を提供します。
標準的なエラーの基準から始めることは、ゼロからスキーマを定義するよりも良い体験を提供するでしょう。

分析ツールはSpan Statusを無視して独自のエラー分析を行ってもよい（MAY）ことに注意してください。
Status Sourceが設定されている場合でも、ステータスコードが尊重されるという要求はありません。
しかし、Status Sourceが設定されている場合、それはオペレーターまたはアプリケーション開発者による主観的な判断を表しているため、分析ツールはそのステータスコードに注意を払うことが強く推奨されます（SHOULD）。

## Remind me why we need status codes again? {#remind-me-why-we-need-status-codes-again}

ステータスコードは、すべての属性やイベントをスキャンすることなく、スパンがエラーバジェットに対してカウントされるかどうかを確認するための、低オーバーヘッドなメカニズムを提供します。
これは、複数の種類のエラーバジェットを追跡するための、安価で低カーディナリティなアプローチです。
これによりオーバーヘッドが削減され、多くのシステムにとって利益となるでしょう。

しかし、その使い方や設定方法を最初に明確に定義しないまま既存のエラー種別のセットを追加したことが、混乱を引き起こしました。
ステータスコードが一貫して正しく設定されなければ、結果として得られるエラーバジェット管理は役に立ちません。
そこで私たちは、この状況を避けるために、すべてのエラー種別を単一の `ERROR` 種別に統合します。
使用事例とそれらを一貫して適用する方法について合意できれば、より多くのエラー種別を後で追加するかもしれません。

## 未解決の問題 {#open-questions}

Collectorにエラー処理を追加した場合、そのオーバーヘッドがどの程度になるかは不明です。

また、計装からエラーが存在する可能性があるというヒントがない状態で、バックエンドがすべてのスパンをスキャンしてエラーを探すコストがどの程度になるかも不明です。

## 先行技術と代替技術 {#prior-art-and-alternatives}

OpenTracingでは、Collectorとステータスマッピングスキーマが存在しないことが扱いにくいことが判明しました。
これは、計装プラグインの作者にエラーフラグを正しく設定する負担を課し、デフォルトのエラーフラグ付けを調整するためだけに、すべてのプラグインで標準化されていない設定オプションが爆発的に増加する結果を招きました。
これは、今度はアプリケーション開発者に設定の負担を課すことになりました。

代替案として、ステータスコードの削除と組み合わせた `error.hint` 提案があります。
これでも機能するでしょうが、本質的にはこの提案で提供されるのと同じメカニズムを、多数の破壊的変更を伴う形で提供するだけです。
また、ユーザーによる上書きの必要性にも対応していません。

## 今後の課題 {#future-work}

ステータスコードとステータスマッピングを含めることは、エラー報告に関してOpenTelemetryコミュニティが同じ言語を話すのに役立ちます。
これは将来の分析ツールの負担を軽減し、（尊重される場合には）ユーザーが複数の分析ツールにわたって重要な設定を同期させることなく、複数の分析ツールを利用できるようにします。

将来的には、OpenTelemetryはステータスマッピングスキーマの動的な設定を可能にするコントロールプレーンを追加するかもしれません。

