サービス連携の”謎解き”を可能にするDatadogによる分散トレース導入の第一歩
by
hirosi1900day
×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
徳富 博(プラットフォームエンジニアリング1G) サービス連携の”謎解き”を可能にする Datadogによる分散トレース導入の第一 歩 @yannKazu1 SRE NEXT 2025
Slide 2
Slide 2 text
自己紹介
Slide 3
Slide 3 text
自己紹介 徳富 博(@yannKazu1) - 所属: タイミー プラットフォームエンジ ニアリングチーム 1G - 好きな技術: Go, Ruby, TypeScript, AWS, … - 野菜を育ててます
Slide 4
Slide 4 text
分散トレーシングについて
Slide 5
Slide 5 text
分散トレーシングとは??
Slide 6
Slide 6 text
分散トレーシングは、システムをまたいだリクエストの流れをエンドツーエンドで可視化 ・追跡する技術です。
Slide 7
Slide 7 text
Propagator? SpanContext? Carrier? サービス間の分散トレーシングを行うとなるといろんな概念が出てきて よくわからなくなる
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
HTTP Headerはどう言う形式で送ればいい?
Slide 10
Slide 10 text
サービス間の分散トレース情報連携の主な方式(HTTPヘッダー、Datadogの場合) 🐶 Datadog 独自形式(datadog) ● x-datadog-trace-id: ● x-datadog-parent-id: ● x-datadog-sampling-priority: ● Datadog APM向けのデフォルト形式 🌐 W3C Trace Context(標準規格、 tracecontext) ● traceparent: --- ● OpenTelemetryなど多くのベンダーが対 応 ⚠ B3(非推奨) 🔹 B3 Multi(b3multi) ● X-B3-TraceId: ● X-B3-SpanId: ● X-B3-ParentSpanId: (任意) ● X-B3-Sampled: 0 または 1 ● Zipkin互換。レガシー用途。複数ヘッダ形 式。 🔸 B3 Single(b3 single header, b3single) ● b3: -- ● 軽量・1ヘッダで伝播。モダンなgRPCや HTTP/2と相性が良い。
Slide 11
Slide 11 text
こういう実装をすれば良いのか? と思った人も多いのではないでしょうか
Slide 12
Slide 12 text
悪くはないがメンテナンス性はよくない ● ヘッダー仕様が変わったとき毎回修正が必要 ● それぞれのサービスが Datadog形式なのか、 tracecontext 形式なのかを意識して実装しないといけないのがつらい。
Slide 13
Slide 13 text
ddtraceには(otel sdkにもあるが省略)、トレース情報をヘッダーに埋め込 んだり取り出したりする仕組み(Inject/Extract)メソッドが用意されて いる
Slide 14
Slide 14 text
送信側
Slide 15
Slide 15 text
受信側
Slide 16
Slide 16 text
Inject/Extractを使えば、環境変数を変えるだけで、tracecontext 形式・datadog形式・両対応など、柔軟に伝搬形式を切り替えられ ます。 ヘッダー伝搬形式の切り替え( ddtrace) ● DD_TRACE_PROPAGATION_STYLE ○ Inject/Extract両方に適用 ○ デフォルトは datadog,tracecontext(両対応) ● DD_TRACE_PROPAGATION_STYLE_INJECT / ..._EXTRACT ○ 各々個別に指定も可能 → Inject/Extractを使えば、簡単に複数の形式(ddtrace形式・tracecontext形 式など)に対応させることができ、形式を意識しなくてよくなる
Slide 17
Slide 17 text
トレース情報をヘッダーに埋め込んだり取り出したりする時 は自前実装ではなくSDKの Inject/Extractを使おう!
Slide 18
Slide 18 text
ところでここって何をやっているんだ?
Slide 19
Slide 19 text
No content
Slide 20
Slide 20 text
No content
Slide 21
Slide 21 text
まずはHTTPHeadersCarrier
Slide 22
Slide 22 text
No content
Slide 23
Slide 23 text
● HTTPHeadersCarrierはhttp.Headerのラッパー ● TextMapWirter, TextMapReaderインターフェースを満たしてい る https://github.com/DataDog/dd-trace-go/blob/cde886e584560f55306cbe0d302eb54d66b88cfc/ddtrace/tracer/textmap.go#L24-L27
Slide 24
Slide 24 text
● TextMapWriter Interface は Set メソッドを持っていて、トレースコンテキ ストを HTTP ヘッダーに詰めるときに使う。 ● TextMapReader Interface は ForeachKey メソッドを持っていて、HTTP ヘッダーから トレースコンテキストを取り出すときに使う。 https://github.com/DataDog/dd-trace-go/blob/0e41cff05e9ed88c9ace780284322acbcbc37574/ddtrace/tracer/propagator.go#L25-L38
Slide 25
Slide 25 text
今回は HTTPHeadersCarrier を使用したが... ● Inject / Extract で使う Carrier(キャリア) は TextMapWriter / TextMapReader インターフェースを満たしていれば OK ● そのため、自作の構造体を使ってカスタマイズした Carrier を作ることも可能
Slide 26
Slide 26 text
tracer(Inject/Extract)
Slide 27
Slide 27 text
No content
Slide 28
Slide 28 text
tracer.InjectはPropagator.Inejectを呼び出す https://github.com/DataDog/dd-trace-go/blob/0e41cff05e9ed88c9ace780284322acbcbc37574/ddtrace/tracer/tracer.go#L841
Slide 29
Slide 29 text
tracer.ExtractはPropagator.Extractを呼び出す https://github.com/DataDog/dd-trace-go/blob/0e41cff05e9ed88c9ace780284322acbcbc37574/ddtrace/tracer/tracer.go#L878
Slide 30
Slide 30 text
Propagator.Inejectの実装 https://github.com/DataDog/ dd-trace-go/blob/b7f198c8d bd42202c46fe191ca68b931 009ab042/ddtrace/tracer/te xtmap.go#L428-L471 TextMapWriter の Set メソッ ドを使って、トレースコンテキ ストを HTTP ヘッダーに書き 込んでいる
Slide 31
Slide 31 text
Propagator.Extractの実装 https://github.com/DataDog/ dd-trace-go/blob/b7f198c8d bd42202c46fe191ca68b9310 09ab042/ddtrace/tracer/text map.go#L510-L571 TextMapReader の ForeachKey メソッドを 使って、HTTP ヘッダーか らトレースコンテキストを読 み取っている
Slide 32
Slide 32 text
● Tracerの Inject や Extract によるトレースコンテキストの詰め替え処理は、実 際には Propagator が担当します。 ● Propagator は、トレースコンテキストを HTTP ヘッダー(HTTP Header Carrier 使用時)に埋め込む・取り出すロジックを持ちます。 ● Propagatorの処理ではCarrier の set メソッドを使って、ヘッダーにトレース情 報を書き込み、foreachKey メソッドを使って、ヘッダーからトレース情報を読 み取ります。
Slide 33
Slide 33 text
今回は組み込まれているPropagatorを使用してますが Propagator は インターフェースを満たしていれば何でも 指定できる。
Slide 34
Slide 34 text
Propagator interface の定義 https://github.com/DataDog/dd-trace-go/blob/0e41cff05e9ed88c9ace780284322acbcbc37574/ddtrace/tracer/propagator.g o#L14-L20
Slide 35
Slide 35 text
tracer.Start 時に WithPropagator オプションを指定することで、独自の Propagator を適用することも可能。
Slide 36
Slide 36 text
Propagator / Carrier を自作する場面 ● Datadogが対応していないプロトコルや形式を使う場合 ● トレース情報の伝搬を制御したい場合 ● カスタムフォーマットが必要な場合
Slide 37
Slide 37 text
まとめ
Slide 38
Slide 38 text
まとめ ● サービス間連携 ○ トレース情報をHTTPヘッダーに手動で仕込むのではなく、各SDKが提供する Inject/Extractメソッドを使用しましょう。 ○ これにより、環境変数(DD_TRACE_PROPAGATION_STYLE)を切り替えるだけ で、Datadog形式、tracecontext形式など柔軟にヘッダー伝搬形式に対応でき ます。 ● 詳細な仕組み: PropagatorとCarrier ○ Inject/Extractメソッドは内部でPropagatorを呼び出します。 ○ PropagatorはSpanContextの情報をCarrier通じてHTTP Headerに 詰めたり、読み取ってSpanContextを生成する役割を担います。 ○ Carrierは、HTTPヘッダーなどの情報伝達媒体を抽象化したラッパーであり、 TextMapWriter(書き込み用)とTextMapReader(読み取り用)インターフェース を実装します。 ○ インターフェースを満たしていれば、カスタムのPropagatorやCarrierを実 装することも可能です。
Slide 39
Slide 39 text
Give distributed tracing a try!