Slide 1

Slide 1 text

Datadog Japan G.K. Kento Kimura(𝕏: @AoToLog_), Keisuke Sakasai(𝕏: @k6s4i53rx) May 22nd, CNDS 2024 pre-event in Tokyo 分散トレースを理解する! Trace Context 解体新書 GENERAL USE

Slide 2

Slide 2 text

Self-Introduction: Co-Speaker ● 所属:Datadog Japan    Technical Solutions / Sales Engineer ● コミュニティ(出没): ○ Jagu'e'r, JAWS, CloudNative, ex-AWS Jr. Champ ● 肩書:Google Cloud Partner Top Engineer 2023-24  2022-23 APN All AWS Certifications Engineer  AWS Community Builder(Cloud Operations, since 2024) ● 登壇:CloudNative Days Fukuoka 2023 pre-event in Tokyo 「サーバレス関数って何を監視すればいいの?」 ● 属性:逆井さんの先輩になってしまった一般人 木村 健人 (Kento Kimura) Datadog Japan GK Technical Solutions Sales Engineering

Slide 3

Slide 3 text

Self-Introduction: Co-Speaker ● 所属:Datadog Japan    Technical Solutions / Sales Engineer ● コミュニティ: ○ OpenTelemetry Meetup スタッフ ○ Google Cloud Champion Innovators コミュニティ 逆井 啓佑 (Keisuke Sakasai) Datadog Japan GK Technical Solutions Sales Engineering ◆ 技術書典 16  俺たちのxQL完全ガイド  - PromQL / LogQL / TraceQL 編 -  日程:5/26(日)  場所:池袋・サンシャインシティ

Slide 4

Slide 4 text

話すこと・話さないこと 話すこと • 分散トレースとは何か • トレースとスパンデータの構造 • HTTP のトレースの伝搬 • OpenTelemetry の話 話さないこと • オブザーバビリティとは何か • トレース以外のテレメトリー • HTTP 以外のトレースの伝搬 • Datadog の話 登壇のきっかけ CloudNative Days にプロポーザルを出すにあたり Datadog に Join する逆井さんとあれこれ 会話していた。個人的に、「分散トレースなんもわからん」期に突入していたので、これを機 に徹底的に調べ上げ発表することに…! 理論は木村、実践は逆井でお送りします😄

Slide 5

Slide 5 text

Agenda 01 分散トレース総論 02 トレースの構成要素 03 Trace Context 論 04 OpenTelemetry Traceを絡めて理解を深める

Slide 6

Slide 6 text

分散トレース総論

Slide 7

Slide 7 text

分散トレース概論 分散トレースは、単に相互に関連した一連のイベントです。 分散トレースとは、1つのリクエストがアプリケーションを構成する 様々なサービスによって処理される過程する追跡する方法です。 分散トレースは、オンプレミスからクラウドインフラ、あるいは (中略)リクエストがまたぐ場合はいつでも問題の診断、コードの 最適化、より信頼できるサービスの構築にたいへん有効です。 “ “ “ “ “ “

Slide 8

Slide 8 text

分散トレースの歴史 分散トレースが主流となったのは、2010年の Google より発表された Dapper の論文から その後、オープンソースプロジェクトとして Zipkin, Jaeger、商用ソリューションも多く登場 2019年には標準化とオープンソースプロジェクトの統合が達成され現在に至る 2010 Dapper Google の大規模分散システムのト レーシング技術 2012 Zipkin(OpenZipkin) Twitter 社のアプリパフォーマンス チューニングツールのOSS化 2017 Jaeger   Uber による分散トレース技術 CNCF に寄贈されたプロジェクト 2016・2017 OpenTracing OpenCensus   いろいろあって統合 2019 W3C Trace Context トレース伝搬仕様の標準化 2019 OpenTelemetry 唯一のオープンソース標準 引用: A History of Distributed Tracing

Slide 9

Slide 9 text

分散トレースの要素① 分散トレースを実現するためには、トレースを収集するための仕組みを施す「計装」、 それらのトレースデータを信頼性・効率性を担保してバックエンドに送信する「転送」、 収集されたトレースデータをバックエンドで分析する「可視化」が必要 Input Output Service 計装 転送 Backend 可視化 ◆ 参考 ・OpenTelemetryのここ4年の流れhttps://speakerdeck.com/ymotongpoo/opentelemetry-in-last-4-plus-years ・計測の手間を省きたい!OpenTelemetry に見る”自動計装”のイマ: https://speakerdeck.com/k6s4i53rx/getting-started-auto-instrumentation-with-opentelemetry

Slide 10

Slide 10 text

分散トレースの要素② 分散トレースのためにアプリケーションに施す計装は、言語ごとの API の実装が存在し、 API の実装を利用する方法として用意された SDK が存在する。 テレメトリデータのエンコーディング・データ交換のためのプロトコルが定義される。 転送 可視化 計装 SDK API 計装 SDK API プロトコル プロトコル プロトコル 伝搬

Slide 11

Slide 11 text

トレースの構成要素

Slide 12

Slide 12 text

トレースデータ解剖 トレースデータの重要な2つの要素 • トレースはアプリケーションのリクエストを処理時間とリクエストステータスを記録する • トレースは1つ以上のスパンで構成される スパンデータの重要な2つの要素 • スパンは特定の期間における分散システムの論理的な作業単位 • 1つ以上のスパンの集合でトレースが構成される

Slide 13

Slide 13 text

スパンデータ解剖 (OpenTelemetry) ● スパンコンテキスト(Span Context): トレース間で伝搬するスパンの情報。TraceContext ● スパン名(Span name): スパンの名前。スパンによって表される作業を簡潔に識別する。 ● スパン種別(SpanKind): スパンの種別。親子関係を識別する。SERVER/CLIENT etc ● 開始/終了時間(Timestamp): 開始時刻はスパンの作成時。終了時刻は操作の終了時。 ● 属性(Attributes): リクエストと他テレメトリを関連付けるキーと値のペア。スパンタグ。 ● スパンリンク(Span links): 他のスパンコンテキストへのリンク。トレース内外のスパンで可能。 ● イベント(Events): イベント名・タイムスタンプ・属性で定義される。 ● ステータス(Status): OK/Error を指定。Error の場合は Description がつけられる。 デフォルトは Unset となる。 Span name(SpanKind: SOMETHING, Status: Unset) 開始時間 終了時間 Root span(Parent span) Child span スパン コンテキスト スパン コンテキスト トレース コンテキスト

Slide 14

Slide 14 text

トレースの可視化 スパンデータから成るトレースの可視化は、 その観点によって複数存在する。 単一の可視化方法だけでなく、複数の視点から 可視化を行うことが重要。 ● ウォーターフォール ● フレームグラフ ● スパンリスト ● トレースマップ ● トレースツリー client Shopping Auth Payment email Send email UserDB

Slide 15

Slide 15 text

トレースの可視化: ウォーターフォール 詳細に分析できる一般的なビュー Pros ● 各スパンの折り畳みと展開が可能 ● スパンの親子関係がわかりやすい ● 特定の親スパン配下の可視化がしやすい Cons ● 大量のスパンを一画面に収めづらい client /api /auth /payment /email API /pool /message /dispatch /send-email UserDB

Slide 16

Slide 16 text

トレースの可視化: フレームグラフ 主にプロファイラで用いられるビュー Pros ● トレースが一画面に収まりやすい ● N+1 処理等の大量のスパンを可視化できる ● スパンの前後・親子関係を把握しやすい Cons ● 並列・非同期処理の可視化が難しい clint /api /auth /payment /email API /pool /message /dispatch /send-email UserDB

Slide 17

Slide 17 text

トレースの可視化: スパンリスト スパンの検索や実行時間を把握するビュー Pros ● スパンの検索やソートができる ● 数値で実行時間や割合を確認できる Cons ● 感覚的なアプリ処理の把握が難しい ● スパンの前後関係がわからない ● あくまでも補助的なビュー Span name Duration Exec % Client └/client 6.32ms 13.3% Shopping └/api 5.48ms 6.6% Auth └/auth 1.05ms 1.9% UserDB └UserDB 0.93ms 14.7% Payment └/payment 1.93ms 22.1% └API 0.53ms 8.4% Email ├/email 2.06ms 12% ├/pool 1.13ms 0% ├/message 1.13ms 0% └/dispatch 1.13ms 0% Send email └/send-email 1.30ms 20.6%

Slide 18

Slide 18 text

トレースの可視化: トレースマップ・ツリー サービスの因果関係を可視化するビュー Pros ● サービスの関係がわかりやすい ● リクエストやエラー等が把握しやすい Cons ● スパンの前後関係がわからない ● スパンの実行時間がわからない ● あくまでも俯瞰的なビュー client Shopping Auth Payment email Send email UserDB

Slide 19

Slide 19 text

Trace Context 論

Slide 20

Slide 20 text

W3C Trace Context 分散トレースのコンテキスト情報を伝播するための HTTP ヘッダーと値の形式の定義。 主に TraceParent, TraceState の2つの伝搬フィールドに分割される。 TraceParent • すべてのベンダーが理解できる共通の形式で、受信リクエストの情報を伝搬する   traceparent: {version}-{trace-id}-{parent-id}-{trace-flag} 例)traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 TraceState • ベンダー固有の形式で、追加のベンダー固有のトレースの識別情報を伝搬する   tracestate: {Key1}={Value1}, {Key2}={Value2} 例)tracestate: dd=ss, ot=12345

Slide 21

Slide 21 text

W3C Trace Context による標準化 なぜ標準化? • 複数プロバイダーのデータリンクによる相互運用性の向上 • ベンダー固有のメタデータの保持・伝搬の保証 • トレースを扱うステークホルダー間への業界標準の提供 トレースの転送(MUST) • TraceParent, TraceState ヘッダーは必ず伝搬し、トレースが破損しないようにする必要がある • 通信プロトコルに準拠した伝搬方法がある(後述) トレースへの参加(CAN) • TraceState ヘッダーを修正し、独自情報を含めても良い • TraceState は Key=Value 形式で、利用できる文字・記号・長さに制限がある

Slide 22

Slide 22 text

伝搬(Propagation) HTTP/gRPC ● W3C Trace Context は HTTP Header での伝搬方法に焦点を当てた標準 ● gPRC はHTTP/2 上に実装された RPC プロトコルで、Protocol Buffer を インターフェイス定義言語 ( IDL ) とメッセージ交換形式として定義できる その他(Trace Context Protocols Registry) ● Trace Context Binary Protocol ● 符号なし8ビット整数値のビットとしてバイナリ形式で伝搬 ● Trace Context AMQP Protocol(FPWD: First Public Working Draft) ● traceparent: binary, tracestate: string として伝搬するように定義 ● Trace Context MQTT Protocol(FPWD: First Public Working Draft) ● User properties で伝搬するように定義

Slide 23

Slide 23 text

非標準化: B3 Multiple/Single header Zipkin(Open Zipkin) で利用されているフォーマット オープンソースプロジェクトのため、商用プロダクトが準拠していることが多い マルチヘッダー • B3 属性は複数 HTTP header で伝搬されるのが一般的 • {SamplingState}は Accept: 1, Deny: 0, Debug:d が設定される シングルヘッダー   b3: {TraceId}-{SpanId}-{SamplingState}-{ParentSpanId} 例)b3: bd520db18d3c49648ad0b58825c68f21-c07f5482e1da4b86-0-e1747be2140a4de2 • サンプリングを行う場合はサンプリング状態の b3: {SamplingState} のみを伝搬する 例)X-B3-TraceId: bd520db18d3c49648ad0b58825c68f21   X-B3-SpanId: c07f5482e1da4b86   X-B3-ParentSpanId: e1747be2140a4de2   X-B3-Sampled: 0 X-B3-TraceId: {TraceId} X-B3-SpanId: {SpanId} X-B3-ParentSpanId:{ParentSpanId} X-B3-Sampled: {SamplingState}

Slide 24

Slide 24 text

標準化: W3C distributed context(Baggage) 分散リクエストまたはワークフロー実行に関連付けられた アプリケーション定義のプロパティのセットを表現・伝達するための標準 Trace Context との関係 • Baggage は分散トレースを行うかに関係なく利用できる HTTP header による伝搬 • Baggage: アプリケーション定義のプロパティ表現と伝達の標準化 • TraceState: 分散トレース シナリオを有効にするために必要なメタデータの表現と伝播を標準化 baggage: key1=value1;property1;property2, key2 = value2, key3=value3; propertyKey=propertyValue

Slide 25

Slide 25 text

OpenTelemetry Traceを絡めて 理解を深める

Slide 26

Slide 26 text

OpenTelemetry とは ● テレメトリーデータの収集・送信の標準仕様を定めている ○ ログ / トレース / メトリクス / プロファイル ● 様々な言語の計装ライブラリを提供 ○ Go、Java、Python、C++、JavaScript… ● OpenTelemetry Collector の開発 今回のテーマである 分散トレース も、 OpenTelemetry のライブラリを用いて計装できる Service OTel Collector 監視 バックエンド OTLP OTLP OTLP = OpenTelemetry Protocol 例) ・OTLP ・Datadog Exporter ・Google Cloud Exporter

Slide 27

Slide 27 text

Tracer Span Tracer Provider OpenTelemetry Trace の構成要素 ( 概要 ) Propagator Resource Span Processor Span Exporter Samplar SpanContext Attributes Span Kind Event 等 等 Span Span ◆ 参考 ・OpenTelemetry Trace Spec: https://opentelemetry.io/docs/specs/otel/trace/api/ ・OpenTelemetryこれまでとこれから: https://bit.ly/20220311-o11yconf-otel ・分散トレーシングとOpenTelemetryのススメ @ OCHaCafe Season7 Span

Slide 28

Slide 28 text

OpenTelemetry Trace の構成要素 ( 概要 ) Resource Span Processor Span Exporter Samplar SpanContext Attributes Span Kind Event 等 等 スパンに共通的に付与するタグ(サービス名、Version 等) スパンを処理: BatchSpan Processor / SimpleSpan Processor スパンを送信 スパンをサンプリング: Always On, Off / Random Span Span Span Span Tracer Tracer Provider Propagator ◆ 参考 ・OpenTelemetry Trace Spec: https://opentelemetry.io/docs/specs/otel/trace/api/ ・OpenTelemetryこれまでとこれから: https://bit.ly/20220311-o11yconf-otel ・分散トレーシングとOpenTelemetryのススメ @ OCHaCafe Season7

Slide 29

Slide 29 text

OpenTelemetry Trace の構成要素 ( 概要 ) Resource Span Processor Span Exporter Samplar SpanContext Attributes Span Kind Event 等 等 トレース ID やスパン ID 等 スパンごとに付与するタグ スパンの種別(Client, Server, Internal) イベント名 / Timestamp / イベントログ Span Span Span Span Tracer Tracer Provider Propagator ◆ 参考 ・OpenTelemetry Trace Spec: https://opentelemetry.io/docs/specs/otel/trace/api/ ・OpenTelemetryこれまでとこれから: https://bit.ly/20220311-o11yconf-otel ・分散トレーシングとOpenTelemetryのススメ @ OCHaCafe Season7

Slide 30

Slide 30 text

Propagator OpenTelemetry Trace の構成要素 ( 概要 ) Resource Span Processor Span Exporter Samplar SpanContext Attributes Span Kind Event 等 等 W3C Trace Context、b3 single header など Span Span Span Span Tracer Tracer Provider ◆ 参考 ・OpenTelemetry Trace Spec: https://opentelemetry.io/docs/specs/otel/trace/api/ ・OpenTelemetryこれまでとこれから: https://bit.ly/20220311-o11yconf-otel ・分散トレーシングとOpenTelemetryのススメ @ OCHaCafe Season7

Slide 31

Slide 31 text

OpenTelemetry Trace の構成要素 ( 概要 ) Resource Span Processor Span Exporter Samplar SpanContext Attributes Span Kind Event 等 等 スパンに共通的に付与するタグ(サービス名、Version 等) スパンを処理: BatchSpan Processor / SimpleSpan Processor スパンを送信 スパンをサンプリング: Always On, Off / Random トレースIDやスパンIDなど スパンごとに付与するタグ スパンの種別(Client, Server, Internal) イベント名 / Timestamp / イベントログ Span Span Span Span Tracer Tracer Provider Propagator W3C Trace Context、b3 single header など

Slide 32

Slide 32 text

OpenTelemetry Trace の構成要素 ( 概要 ) サービス A サービス B サービス Z ・ ・ ・ ・ Propagator の設定に基づき、 トレースコンテキストが伝播 トレース バックエンド clint /api /auth /payment /email API /pool /message /dispatch /send-email UserDB ◆ 参考 ・OpenTelemetry Trace Spec: https://opentelemetry.io/docs/specs/otel/trace/api/ ・OpenTelemetryこれまでとこれから: https://bit.ly/20220311-o11yconf-otel ・分散トレーシングとOpenTelemetryのススメ @ OCHaCafe Season7

Slide 33

Slide 33 text

OpenTelemetry Trace のコンテキスト伝播 サービス間のトレースコンテキストの交換は Propagator が担う • W3C Trace Context: go.opentelemetry.io/otel/propagation • b3 single header: go.opentelemetry.io/contrib/propagators/b3 Propagator は仕様として Extract / Inject メソッドを持つ • Extract は HTTP の場合、ヘッダからトレースコンテキストを抽出 • Inject は同様に、ヘッダにトレースコンテキストを注入 Trace ID Span ID 受信 送信 リクエスト リクエスト Trace ID Span ID Extract Inject ※ キャリア構造体は省略

Slide 34

Slide 34 text

OpenTelemetry Trace のコンテキスト伝播 W3C Trace Context での Propagator の実装(extract) func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext { // ヘッダーからトレース情報を取り出す h := carrier.Get(traceparentHeader) // traceparentHeader="traceparent" … // スパンコンテキストの構造体を定義 var scc trace.SpanContextConfig // 構造体にヘッダーのトレース ID をセット if !extractPart(scc.TraceID[:], &h, 32) { return trace.SpanContext{} } // 構造体にヘッダーのスパン ID をセット if !extractPart(scc.SpanID[:], &h, 16) { return trace.SpanContext{} } // ヘッダーから取り出したトレース情報をアクティブなスパンコンテキストとして設定 sc := trace.NewSpanContext(scc) github.com/open-telemetry/opentelemetry-go/blob/main/propagation/trace_context.go#L80-L128

Slide 35

Slide 35 text

OpenTelemetry Trace のコンテキスト伝播 otelhttp のようなパッケージは、 ヘッダーの解析、スパンコンテキストへの設定を行ってくれる計装ライブラリ github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/net/http/otelhttp/handler.go#L134 helloHandler := func(w http.ResponseWriter, req *http.Request) { … // 何かしらの処理 _, _ = io.WriteString(w, "Hello, world!\n") } // otelhttp でラップ // 計装 = ヘッダからトレース情報を抽出して、スパンコンテキストに設定 otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello") // サーバーの起動 http.Handle("/hello", otelHandler) err = http.ListenAndServe(":8080", nil) github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/net/http/otelhttp/example/server/server.go#L82-L97

Slide 36

Slide 36 text

OpenTelemetry Trace のコンテキスト伝播 (補足) ● ここまでコード含めて見てきたように、 トレースコンテキストを取り回すことで分散トレースを実現 ● HTTP じゃなくても、トレースコンテキストをサービス間でやり取りできればトレースを繋げる ことができる(非同期通信の分散トレース) ○ otelsalama (Kafka の Consumer / Producer 用の計装ライブラリ) 参考:Apache Kafka を使った非同期処理で分散トレーシングをする with OpenTelemetry: https://zenn.dev/k6s4i53rx/articles/2fa37a293cf228

Slide 37

Slide 37 text

OpenTelemetry Trace のコンテキスト伝播 (補足) ● ここまでコード含めて見てきたように、 トレースコンテキストを取り回すことで分散トレースを実現 ● HTTP じゃなくても、トレースコンテキストをサービス間でやり取りできればトレースを繋げる ことができる(非同期通信の分散トレース) ○ otelsalama (Kafka の Consumer / Producer 用の計装ライブラリ) 参考:Apache Kafka を使った非同期処理で分散トレーシングをする with OpenTelemetry: https://zenn.dev/k6s4i53rx/articles/2fa37a293cf228 前半学んだ座学を OpenTelemetry の実装に触れながら見ました。

Slide 38

Slide 38 text

分散トレースのお供 (Tips) として

Slide 39

Slide 39 text

● トレースに付与する属性情報 ● Baggage の利用ついて ● 分散トレースと他のテレメトリーの関連付け

Slide 40

Slide 40 text

トレースに付与する属性情報 ● トレーススパンの属性情報 ○ サービス単位で付与: Resource / スパン単位で付与: Attribute ○ 情報量(ディメンション、カーディナリティ)を増やすことで、 テレメトリーデータの探索の切り口が増え、オブザーバビリティを高めることができる ● 方法 ○ ❶ 手動で Resource や Attribute を付与する ○ ❷ 計装ライブラリの利用   https://opentelemetry.io/ecosystem/registry/ ○ ❸ OpenTelemetry Collector で Processor を使う ■ Kubernetes Attributes Processor ■ Resource Detection Processor ● Resource Detection Processor でホスト名と(ディメンション)が付与 20 種類(カーディナリティ)のホストがあり、探索の観点を増やすことができる OTel Collector mongo otelmongo サービスA ホスト名 (例) Resource Detection Processor ❶ ❸ ❷

Slide 41

Slide 41 text

 留意点 ● Baggage に渡すだけでは Span の属性情報には含まれない点 ● Baggage の肥大化リスク ● 参考:"Ask Miss O11y: Baggage in OTel" honeycomb.io/blog/ask-miss-o11y-opentelemetry-baggage Baggage の利用について ● コンテキスト伝播として baggage 使用 ○ Baggage はキーバリュー形式のデータ構造 ○ ヘッダ名は "baggage"。仕様は W3C Baggage に準拠 ● ユースケース例 ○ User IDs, Product IDs, and origin IPs ○ feature flags の実装 otel.SetTextMapPropagator( propagation.NewCompositeTextMapPropagator( propagation.TraceContext{}, propagation.Baggage{}, ), ) opentelemetry.io/docs/concepts/signals/baggage/

Slide 42

Slide 42 text

分散トレースと他のテレメトリーの関連付け テレメトリー同士の関連付けもオブザーバビリティを高める上で重要 ● テレメトリー同士の関連付け ○ ログ ⇔ トレース: ログにトレース ID を付与 ○ メトリクス ⇔ トレース: タイムスタンプやトレースエグザンプラーを使用 ● プロファイルとトレースもトレース情報を使って紐付け。 モニタリングツールによってはダッシュボード上で遷移(一例) ○ Datadog ○ Grafana Pyroscope(v1.2.0)で "Trace to profile" リリース https://github.com/grafana/otel-profiling-go ■ TracerProvider を拡張して、 Span 生成時にサンプルしたプロファイルに SpanID を付与して、Grafana 上で紐付ける仕組み https://grafana.com/docs/pyroscope/next/configure-client/trace-span-profiles/go-span-profiles/ トレース プロファイル

Slide 43

Slide 43 text

分散トレース解体新書 まとめ ● 前半パートでは、 分散トレースの歴史や仕組み、 分散トレースを可視化する上での各ビューについて触れました ● 後半パートでは、 OpenTelemetry Trace の仕様を見ながら、前半の座学を踏まえ実装や (OpenTelemetry で)分散トレースをする上で Tips について紹介しました

Slide 44

Slide 44 text

おわり