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


# OTEP-0002: SpanDataの削除

スパンの開始と終了のオプションを追加して、SpanDataを削除して置き換えます。

## 動機

SpanDataはイミュータブルなスパンオブジェクトを表し、すべてのフィールド（正確には12）に対してかなり大きなAPIを作成します。
SDKの懸念事項や実装の詳細のようなものをAPIサーフェスに公開しています。
ユーザーとしては、これもAPIの使い方を学ばなければならないし、ID生成も公開する必要があるかもしれません。
実装者としては、これはサポートされなければならない新しいデータ型です。
SpanDataを削除する主な動機は、トレーシングAPIのサイズを小さくしたいという願望にあります。

## 解説

SpanDataにはいくつかのユースケースがあります。

最初のユースケースは、同期的にスパンを作成するけれど、開始時刻をより正確なタイムスタンプに変更する必要がある場合です。
たとえば、HTTPサーバーでは、最初のバイトを受信した時刻を記録し、ヘッダーを解析し、スパン名を決定し、スパンを作成します。
スパンが作成された時点は、リクエストが実際に開始された時点の代表ではなく、最初のバイトが受信された時点がスパンの開始時刻となります。
現在のAPIは開始タイムスタンプを許可していないので、SpanDataオブジェクトを作成する必要があります。
大きな欠点は、アクティブなスパンオブジェクトが得られないことです。

2つ目のユースケースは、トレース外のスパンを構築してレポートする必要性から来るもので、つまり、所有していない操作のために「カスタム」スパンを作成することを意味します。
この良い例の1つは、相関IDと期間（たとえばSplunkから）を含む構造化されたログを取り込み、それをトレースシステム用のスパンに変換するスパンシンクです。
別の例としては、HAProxyのマシンでサイドカーを実行し、リクエストログをテイルして、スパンを作成します。
SpanData では、トレース外のレポートケースをレポートすることができます。
一方、現在の Span API では、開始と終了のタイムスタンプを設定することができません。

私は、SpanDataと `tracer.recordSpanData()` を廃止し、`tracer.startSpan()` に開始タイムスタンプのオプションを、`span.end()` に終了タイムスタンプのオプションを指定できるようにすることを提案します。
これは、APIの面を減らし、単一のスパンタイプに統合します。
このオプションは、トレース外報告の要件を満たすでしょう。

## 内部の詳細

`startSpan()` は、オプションで開始タイムスタンプ、スパンID、リソースを含めることができるように変更されます。
スパンシンクがある場合、トレース外のスパンは、報告されるトレーサーとは異なるリソースを持っているかもしれないので、明示的にリソースを渡すのが良いでしょう。
`span.end()` には、オプションで終了タイムスタンプを指定します。
正確な実装は言語によって異なるので、関数のオーバーロードや可変パラメーターを使ったオプションパターンを使うか、スパンビルダーにこれらのオプションを追加することになるでしょう。

## トレードオフと緩和策

<https://github.com/open-telemetry/opentelemetry-specification/issues/71>より引用すると、もしSDKがスパンの開始時に自動的にスレッドID、スタックトレース、CPU使用率などのタグをスパンに追加した場合、トレーサーはトレース内スパンとトレース外スパンの違いを認識できないため、トレース外スパンではタグが正しくありません。
これは、おそらく `startSpan()` の `isOutOfBand()` オプションを使って、スパンがトレース外であることを示し、不正な情報が添付されるのを防ぐことで緩和できます。

## 先行技術と代替技術

OpenTracing の `tracer.startSpan()` の仕様には、オプションで開始タイムスタンプと0個以上のタグが含まれています。
また、`span.end()` では、オプションで終了タイムスタンプと一括ロギングを呼び出します。

## 未解決の問題

また、SpanDataとサンプラーAPIの間には隠れた依存関係があるようです。
たとえば、開始と終了のタイムスタンプを持つ完全なSpanDataオブジェクトが与えられた場合、サンプラーがそれを見て「これは長い時間がかかった」と判断し、サンプリングするようなユースケースがあると想像します。
これは実際のユースケースなのでしょうか。
サンプラーに完全なスパンオブジェクトを提供できるようにする必要があるのでしょうか。

## 今後の課題

サンプラーにサンプリングするためのより多くの情報を与えるために、開始オプションとして属性を含めたいかもしれません。
また、明示的なタイムスタンプを持つイベントを一括で追加するために、オプションのイベントを含めることもできるでしょう。

また、スパンやサブトレースが同じプロセスで作成されることを前提に、タイムスタンプが同じ精度を使用し、モノトニックであることを確認したいでしょう。

## 関連する問題

SpanDataを削除すれば、[open-telemetry/opentelemetry-specification#71](https://github.com/open-telemetry/opentelemetry-specification/issues/71)を解決できます。

オプションは[open-telemetry/opentelemetry-specification#139](https://github.com/open-telemetry/opentelemetry-specification/issues/139)を解決するでしょう。

SpanDataを削除することで、[open-telemetry/opentelemetry-specification#92](https://github.com/open-telemetry/opentelemetry-specification/issues/92)を解決し、クローズできます。

[open-telemetry/opentelemetry-specification#68](https://github.com/open-telemetry/opentelemetry-specification/issues/68)を閉じることができます。
オプションのリソースは、トレース外のスパンに対して異なるリソースを提供でき、そうでなければトレーサーはデフォルトのリソースを提供できます。

[open-telemetry/opentelemetry-specification#60](https://github.com/open-telemetry/opentelemetry-specification/issues/60)は、SpanDataの削除によりクローズできます。

