Open9

rust で otel の trace やる

shusannshusann
at 20:52:28 ❯ tree -d
.
├── author-service
│   └── src
├── book-service
│   └── src
├── gateway
│   └── src
shusannshusann

流れは自明なので一旦描き下ろし (Tracing)

1. TextMapPropagator を登録

trace や baggage といった cross-cuttting edge な Context に情報を詰める責務を持つ Propagator をセットする。

global::set_text_map_propagator(TraceContextPropagator::new());

W3C の TraceContextBaggage に入れたり出したりする。

TextMapPropagator は Propagator のうちの一種類、IF を見ればより具体的なイメージが持てる

https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry/src/propagation/text_map_propagator.rs#L18-L58

この IF を実装した Trace 用の TraceContextPropagator は span_id や trace_id など上の仕様で取り決められた内容について取り扱っている

https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-sdk/src/propagation/trace_context.rs#L142-L146

https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-sdk/src/propagation/trace_context.rs#L58-L117

これを、リクエストを受け付けたタイミングで extract し parent context としてインスタンス化して span を開始する用途に使用する

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/examples/tracing-grpc/src/server.rs#L63-L64

クライアントから送信するときは逆に inject する用途に使う

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/examples/tracing-http-propagator/src/client.rs#L37-L39

2. TracerProvider をインスタンス化 (otlp, datadog, prometheus, aws 等々)

これは、 contrib か 公式 repoExporter を使う。

標準出力に出したいなら opentelemetry_stdout 使うみたいな感じ。 TracerProvider に登録する。

    let provider = TracerProvider::builder()
        .with_simple_exporter(opentelemetry_stdout::SpanExporter::default())
        .build();

3. TracerProvider を global に登録する

global を通じて、set, get を行う。 2 で作成した TracerProvider を登録する。

global::set_tracer_provider(provider);

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry/src/global/trace.rs#L419-L438

4. Tracer を取得する

global に登録した TracerProvider から Tracer のインスタンスを取得する。

let tracer = global::tracer("readme_example");

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry/src/global/trace.rs#L381-L390

shusannshusann

hyper 用の middleware としての TracePropagator の実装は neon がやっていた。(公式 contrib の intrumentation lib はない)

https://github.com/neondatabase/neon/blob/42bda5d6323d6655dd866c01dfa680f8479d7e43/libs/tracing-utils/src/http.rs#L38-L45

https://github.com/neondatabase/neon/blob/42bda5d6323d6655dd866c01dfa680f8479d7e43/compute_tools/src/http/api.rs#L545-L549

opentelemetry crate で exporter を作って、 TracerProvider を tracing_opentelemetry を使って登録している。結構ちゃんぽんなことやってる

shusannshusann

Trace の送信はいくつかのルートが用意されていそう。

examples

https://github.com/open-telemetry/opentelemetry-rust/blob/main/examples/tracing-jaeger/src/main.rs#L32-L44

https://github.com/open-telemetry/opentelemetry-rust/blob/main/examples/tracing-http-propagator/src/server.rs#L47-L52

routes

  1. in_span でクロージャーを渡す方法

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry/src/trace/tracer.rs#L204-L214

  1. span_builder で span を取ってきて使う方法

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry/src/trace/tracer.rs#L158-L172

Span trait には end が定義されているものの、上の in_span でも span_builder でも使われておらず、終了は opentelemetry_sdk の Span の Drop の実装に移譲されている (いいのかこれ: api は sdk の知識を持っておらず終了することを api の実装レベルでは保証していないことになってしまっている)

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry/src/trace/span.rs#L173-L176

https://github.com/open-telemetry/opentelemetry-rust/blob/849778d52432543343d221ff290da5d19412fc7d/opentelemetry-sdk/src/trace/span.rs#L242-L247