rust で otel の trace やる
at 20:52:28 ❯ tree -d
.
├── author-service
│ └── src
├── book-service
│ └── src
├── gateway
│ └── src
contrib 対応しているサーバー見繕う
actix を使ってみる
今回は Jaeger で Collect する
Jeager は適当に docker で立ち上げて、ポートも開けといて放置する。
docker run -d -p16686:16686 -p4317:4317 jaegertracing/all-in-one:latest
流れは自明なので一旦描き下ろし (Tracing)
1. TextMapPropagator を登録
trace や baggage といった cross-cuttting edge な Context に情報を詰める責務を持つ Propagator をセットする。
global::set_text_map_propagator(TraceContextPropagator::new());
W3C の TraceContext や Baggage に入れたり出したりする。
TextMapPropagator は Propagator のうちの一種類、IF を見ればより具体的なイメージが持てる
この IF を実装した Trace 用の TraceContextPropagator は span_id や trace_id など上の仕様で取り決められた内容について取り扱っている
これを、リクエストを受け付けたタイミングで extract し parent context としてインスタンス化して span を開始する用途に使用する
クライアントから送信するときは逆に inject する用途に使う
2. TracerProvider をインスタンス化 (otlp, datadog, prometheus, aws 等々)
これは、 contrib か 公式 repo の Exporter を使う。
標準出力に出したいなら 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);
4. Tracer を取得する
global に登録した TracerProvider から Tracer のインスタンスを取得する。
let tracer = global::tracer("readme_example");
hyper 用の middleware としての TracePropagator の実装は neon がやっていた。(公式 contrib の intrumentation lib はない)
opentelemetry crate で exporter を作って、 TracerProvider を tracing_opentelemetry を使って登録している。結構ちゃんぽんなことやってる
Trace の送信はいくつかのルートが用意されていそう。
examples
routes
- in_span でクロージャーを渡す方法
- span_builder で span を取ってきて使う方法
Span trait には end が定義されているものの、上の in_span でも span_builder でも使われておらず、終了は opentelemetry_sdk の Span の Drop の実装に移譲されている (いいのかこれ: api は sdk の知識を持っておらず終了することを api の実装レベルでは保証していないことになってしまっている)