Slide 1

Slide 1 text

1 仕様と実装で学ぶ OpenTelemetry Drumato/菅原 ⼤和 技術部プラットフォームグループ 2024.5.9

Slide 2

Slide 2 text

2 ⾃⼰紹介 技術部 プラットフォームグループ 2024年 中途⼊社 菅原 ⼤和 Yamato Sugawara ● 業務: カラーミーショップのKubernetes運⽤、 OpenTelemetry導⼊を率先、その他 ● 好きな分野: ネットワーク/K8s/プログラミング ● 趣味: カラオケ/ゲーム/ドラム/技術 ● 上から下まで全部⾒たいSRE ● とにかくコードも書きたいSRE ● X : @drumato

Slide 3

Slide 3 text

3 アジェンダ 1. Go SDKと合わせて理解するOpenTelemetryの仕様(いけるとこまで) 2. Zigで作るSDKミニマルサブセット

Slide 4

Slide 4 text

4 OpenTelemetry, 使ってますか?

Slide 5

Slide 5 text

5 OpenTelemetryの Specificationを読んだことは ありますか?

Slide 6

Slide 6 text

6 OpenTelemetryの SDK実装を読んだことは ありますか?

Slide 7

Slide 7 text

7 この発表でわかること 1. OpenTelemetry仕様の⼀部にふれることでちょっとだけ詳しくなれます 2. OpenTelemetry Go SDK(の⼀部)を読むことで実装を理解します 2.1. 拡張性のあるGoライブラリ実装パターン 2.2. OpenTelemetry SDKの実装における共通点、API設計 2.3. SDKを使うときの挙動把握

Slide 8

Slide 8 text

8 この発表でわからないこと 1. OpenTelemetryの具体的な活⽤⽅法については扱いません 2. OpenTelemetry SDKの使い⽅については扱いません 3. 時間の都合上、カラーミーショップにおけるOpenTelemetryの取り組み は紹介しません 4. OTLPには触れません 4.1. 次回、詳解OTLP編でお会いしましょう

Slide 9

Slide 9 text

3. OpenTelemetryの仕様 21

Slide 10

Slide 10 text

仕様をひたすらに読むのはつらい 22

Slide 11

Slide 11 text

「実装」も合わせて理解しよう 23

Slide 12

Slide 12 text

OpenTelemetryの仕様 24 OpenTelemetry SDKリーディングで理解するOtel仕様 • OpenTelemetry Go SDKの実装⽚⼿に仕様を理解する • OpenTelemetryの仕様はプログラミング(実装)を強く意識した書き⽅がされている • 特定の実装に依存しているわけではない • 「OpenTelemetry APIはライブラリ上でかくあるべき」というレベルで具体的 • 注: Go SDKのLogs APIは2024年5⽉現在Alpha

Slide 13

Slide 13 text

OpenTelemetryの仕様 25 • OpenTelemetry Specification • OpenTelemetryで扱われるデータ構造や概念の定義、各エコシステムが満た す仕様と実装⽅針まで • OpAMP • Agentをリモートで設定管理するためのプロトコル定義 • 今回は扱わない • OTLP Specification • シグナルを送受信するプロトコルについて定義 • Semantic Convention • DBやHTTPアプリケーションなど、対象システムが推奨されるルールが定義 OpenTelemetryの仕様概要

Slide 14

Slide 14 text

OpenTelemetryの仕様 26 • OpenTelemetryで扱われるデータ構造や⽤語の定義、それぞれのデータ構造に⾏え る操作を定義した仕様 • Contextとは?Trace IDは何バイト(ビット)?Span Attributeの命名規則は? • 本発表ではOTLPの仕様と区別して呼称 • OTLP Specificationとして、次のスライドで解説 • oteps(OpenTelemetry Enhanced Proposals)で新しい仕様が提案されていたりする OpenTelemetry Specificationとは

Slide 15

Slide 15 text

OpenTelemetryの仕様 27 • テレメトリの送受信に⽤いるThe OpenTelemetry Protocol(以下OTLP)の定義 • OTLP/gRPC … Underlying ProtocolとしてgRPCを使う • gRPC/Protobufを⽤いてメッセージフォーマットを定義 • →定義に従ったメッセージならどのようなプログラムからのメッセージも正常受理される • OTLP/HTTP … Underlying ProtocolとしてHTTP1.1/HTTP2を使う • 上記protobuf定義に対応するJSONをPOSTする • どちらもネットワークレイテンシを考慮して、Concurrent Requestsをサポートする 必要がある(SHOULD) • 本発表では時間の都合上、これ以上は解説しません OTLP Specificationとは

Slide 16

Slide 16 text

OpenTelemetry Specification 28 • 以下のパートで構成 • Client Design Principles • API Specification • SDK Specification • Data Specification • それぞれTracing/Logs/Metricsで分けて定義されている • 今回はTracingだけを扱う OpenTelemetry Specification

Slide 17

Slide 17 text

OpenTelemetry Specification 29 • /context … プロセス内のContext伝搬 • /metrics … Metrics API • /trace … Tracing API • /baggage … • /internal … 公開しない内部実装 • /logs … Logs API Package Layout-API- https://opentelemetry.io/docs/specs/otel/library-layout/

Slide 18

Slide 18 text

OpenTelemetry Specification 30 Package Layout-API- https://github.com/open-telemetry/opentelemetry-go

Slide 19

Slide 19 text

OpenTelemetry Specification 31 Package Layout-API- https://github.com/open-telemetry/opentelemetry-go Goではプロセス内伝搬に context.Contextを⽤いるため /contextはない

Slide 20

Slide 20 text

OpenTelemetry Specification 32 • OpenTelemetryライブラリが実現しなければならないパフォーマンスとブロッキン グの性質、並⾏制御の挙動について定義 • 例: Tracing APIの場合 • Span/Tracer/TracerProviderのすべてのメソッドはスレッド安全 • Event/Linkはイミュータブルでありスレッド安全なデータ構造 Performance, Blocking, Concurrency, and Thread-Safety https://opentelemetry.io/docs/specs/otel/performance/ https://opentelemetry.io/docs/specs/otel/library-guidelines/#concurrency-and-thread-safety

Slide 21

Slide 21 text

3-1. Client Design Principles 33

Slide 22

Slide 22 text

OpenTelemetry Specification 34 Client Design Principles https://opentelemetry.io/docs/specs/otel/library-guidelines/#opentelemetry-client-generic-design • フレームワークやライブラリなどはOpenTelemetry APIにのみ依存するようにできる こと • フレームワークやライブラリを使った最終的な成果物でのみSDKや代替実装を差し込んで利 ⽤できること

Slide 23

Slide 23 text

OpenTelemetry Specification 35 Client Design Principles https://opentelemetry.io/docs/specs/otel/library-guidelines/#opentelemetry-client-generic-design

Slide 24

Slide 24 text

OpenTelemetry Specification 36 Client Design Principles APIとSDKが 分かれている https://opentelemetry.io/docs/specs/otel/library-guidelines/#opentelemetry-client-generic-design

Slide 25

Slide 25 text

3-2. API Specification 37

Slide 26

Slide 26 text

OpenTelemetry Specification 38 • execution unit間や、API境界を横断する情報伝播に⽤いられる • execution unitは、Glossaryにて「スレッドやコルーチン、ファイバーに代表される実⾏単位」と されている • Contextはimmutableであり、変更APIは「差分適⽤されたContextを返す」べき(MUST) • 以下の操作を持つと定義 • GetValue(key) … コンテキストが内包するkeyに紐づくデータを取得 • SetValue(key, value) … (key, value)という組を内包する新しいコンテキストを初期化し返す • 上記以外にもOptionalとしていくつか操作が定義されている API Specification-Context-1/2 https://opentelemetry.io/docs/specs/otel/context/

Slide 27

Slide 27 text

OpenTelemetry Specification 39 • Goのcontextパッケージは先述した要件をそのまま満たす標準パッケージ API Specification-Context-2/2 https://pkg.go.dev/context

Slide 28

Slide 28 text

OpenTelemetry Specification 40 • アプリケーション側で独⾃にテレメトリデータに付加情報をつけるために⽤いられる • 具体的な定義は W3C Baggage Specification • これ⾃体は分散システムにおけるコンポーネント間のユーザ定義情報を伝搬させるための機能 • OpenTelemetryは仕様上のデータをContextで, それ以外のユーザ定義情報をBaggageで伝搬 API Specification-Baggage- https://opentelemetry.io/docs/specs/otel/baggage/api/

Slide 29

Slide 29 text

OpenTelemetry Specification 41 • 横断的なデータを伝搬するために⽤いる • W3C TraceContextやBaggageをプロセス間で取り回すための便利API、というイメージで良い • それぞれのユースケースごとにInterceptorを⽤意して抽出・挿⼊を⾏う • 例: HTTPサーバではHTTPリクエストから⽂脈を抽出し、トレースデータに挿⼊する • 現在はTextMapPropagator だけ⽤意しておけば良いということになっている • TextMapPropagator … ⽂字列のキーバリューの組を扱うPropagator オブジェクト • BinaryPropagator というのも提案されている(が今は標準化されていない API Specification-Propagators-1/3 https://opentelemetry.io/docs/specs/otel/context/api-propagators/

Slide 30

Slide 30 text

OpenTelemetry Specification 42 API Specification-Propagators-2/3 https://pkg.go.dev/go.opentelemetry.io/[email protected]/propagation#TextMapPropagator

Slide 31

Slide 31 text

OpenTelemetry Specification 43 API Specification-Propagators-3/3 https://github.com/open-telemetry/opentelemetry-go/blob/2f662dbe131bb499e63dc99b66605722fcb4d761/propagation/trace_context.go • W3C TraceContextの実装 • フォーマットに従った⽂字列構築 • その後carrierに書き込む • FlagsSampled については後述

Slide 32

Slide 32 text

OpenTelemetry Specification 44 • PropagatorがContextやBaggageを扱う際にどのようなパス/箱で、伝搬するか/されるか を抽象化したAPI • 例: HTTP経由で伝搬される⽂脈を扱う場合には、HTTPヘッダをCarrierとする API Specification-Carrier-1/3 https://opentelemetry.io/docs/specs/otel/context/api-propagators/#carrier

Slide 33

Slide 33 text

OpenTelemetry Specification 45 API Specification-Carrier-2/3 https://pkg.go.dev/go.opentelemetry.io/[email protected]/propagation

Slide 34

Slide 34 text

OpenTelemetry Specification 46 API Specification-Carrier-3/3 https://github.com/open-telemetry/opentelemetry-go/blob/2f662dbe131bb499e63dc99b66605722fcb4d761/propagation/propagation.go • シンプルな実装

Slide 35

Slide 35 text

OpenTelemetry Specification 47 API Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/api/ • 以下3つで構成 • TracerProvider … Tracerを構成する設定を持つステートフルオブジェクト • グローバルなProviderを利⽤できるようにすべき(SHOULD) • Tracer … Span⽣成に責任を持つAPI • Tracer以外のAPIでSpan⽣成できるようになっていてはならない(MUST NOT) • Span … トレース内のあるオペレーションを表現する単位

Slide 36

Slide 36 text

OpenTelemetry Specification 48 API Specification-Tracing- https://pkg.go.dev/go.opentelemetry.io/otel/trace

Slide 37

Slide 37 text

OpenTelemetry Specification 49 API Specification-Tracing- https://pkg.go.dev/go.opentelemetry.io/otel/trace

Slide 38

Slide 38 text

OpenTelemetry Specification 50 API Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/api/#span • Spanの中⾝ • name • SpanContext • 親Spanの情報(SpanでもSpanContextでも) • SpanKind(CLIENT/SERVER/PRODUCER/CONSUMER/INTERNAL) • 開始/終了タイムスタンプ • Link(s) • Event(s) • Status

Slide 39

Slide 39 text

OpenTelemetry Specification 51 API Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/api/#spancontext • Spanのうち、分散トレーシング環境において伝搬する必要のある情報はSpanContextと して別に定義されている • Contextというワードが混雑してきたので整理 • Context … execution unit間で情報伝播できるようにする普遍的なAPI/データ構造の概念 • W3C TraceContext … W3Cで定義されている、分散トレーシングにおけるトレーシング⽂脈の情 報伝搬に使われるデータフォーマット • Go SDKではPropagatorの実装として存在している • SpanContext … Spanの情報のうち伝搬しなければいけない情報の総称で、W3C TraceContext に準拠している

Slide 40

Slide 40 text

OpenTelemetry Specification 52 API Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/api/#spancontext • SpanContextの中⾝ • TraceId … トレースの識別⼦であり、16byte(128bit) • SpanId … 各Spanの識別⼦であり、8byte(64bit) • TraceFlags … トレースごとのフラグ、現在はSampledのみ利⽤されている • TraceState … 独⾃に使われる領域で、W3C TraceContextで定義されている • IsRemote … SpanContextが伝搬されてきたものなのか、ローカルで⽣成されたのか

Slide 41

Slide 41 text

OpenTelemetry Specification 53 API Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/api/#add-link • Spanは別のSpanContextとLinkを結べるようになっていなければならない(MUST) • Linkは異なるトレース間のSpanContextでも結べるようになっている

Slide 42

Slide 42 text

3-3. SDK Specification 54

Slide 43

Slide 43 text

OpenTelemetry Specification 55 SDK Specification-Tracing- https://opentelemetry.io/docs/specs/otel/trace/sdk/ • ⾮常に⼤きいので、いくつかピックアップして紹介

Slide 44

Slide 44 text

OpenTelemetry Specification 56 SDK Specification-Sampling- https://opentelemetry.io/docs/specs/otel/trace/sdk/#sampling • 収集/送信するトレース情報をサンプルすることでオーバーヘッドおよびノイズを軽減す る仕組み • IsRecording と Sampled という2つの重要なフラグがある • IsRecording … Spanにつけられるフラグで、そのSpanが記録されるべきという意味 • SpanProcessor はIsRecordingがtrueのもののみ対象として処理する • Sampled … SpanContextのTraceFlagsにつけられるフラグ • W3C TraceContextに詳しい定義が書いてある • サンプリングアルゴリズムによって選出されたSpanであることを表す • SpanExporterはSampled Spanを必ず受信する(MUST) • SimpleSpanProcessorにおける対応処理

Slide 45

Slide 45 text

OpenTelemetry Specification 57 SDK Specification-ID Generator- https://github.com/open-telemetry/opentelemetry-go/blob/2f662dbe131bb499e63dc99b66605722fcb4d761/sdk/trace/id_generator.go#L16-L35

Slide 46

Slide 46 text

OpenTelemetry Specification 58 SDK Specification-Span Processor- • Spanのstart()/end()にフックして呼び出されるオブジェクトを抽象化したもの • 即時処理するSimpleと、バッチ処理するBatchの実装が存在 • それぞれのProcessorがExporterを内包していて、OTLP経由で送信する • SDKではSpanがTracerを参照し、TracerがTracerProviderを参照し、TracerProviderに Processorが初期化されているので、すべてがSpanから⾒える状態になっている • それぞれはmutex等で排他制御されているので、goroutineで並⾏アクセスしても動く https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-processor

Slide 47

Slide 47 text

OpenTelemetry Specification 59 SDK Specification-Span Processor- https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-processor

Slide 48

Slide 48 text

OpenTelemetry Specification 60 SDK Specification-Span Processor- https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/trace/simple_span_processor.go#L44C1-L54C2

Slide 49

Slide 49 text

OpenTelemetry Specification 61 SDK Specification-Span Exporter- • OTLP/HTTPやOTLP/gRPCなど、Span送信に責任を持つコンポーネント • Export/Shutdown/ForceFlushという3つの操作が定義されている(MUST) • Export … Readable Span(s)を送信する • 無期限にブロックされてはならない(MUST NOT) • Shutdown … SDKのシャットダウンをトリガーに呼び出される • クリーンアップ処理を⾏ったりする • ForceFlush … 送信されていないSpan(s)をすべて送信する • concurrent requestと再送処理の実装はExporterの責務 https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-exporter

Slide 50

Slide 50 text

OpenTelemetry Specification 62 SDK Specification-Span Exporter- https://github.com/open-telemetry/opentelemetry-go/blob/main/exporters/otlp/otlptrace/exporter.go

Slide 51

Slide 51 text

OpenTelemetry Specification 63 SDK Specification-Configuration- • 環境変数でなにが設定できるか等々が定義されている • よくみる OTEL_EXPORTER_OTLP_TRACES_ENDPOINT とかです https://opentelemetry.io/docs/specs/otel/configuration/

Slide 52

Slide 52 text

3-4. Data Specification 64

Slide 53

Slide 53 text

OpenTelemetry Specification 65 Data Specification-Semantic Conventions- • Span/Event/Metrics/Logsで対応しておくべき情報が列挙されている • MUSTではなくOptionalだったり、そもそもexperimentalだったりする • あまりに多いのでここでは紹介しません • open-telemetry/semantic-conventions にすべてが書いてあります • 例1: どのログにも log.record.uid attributeを⼊れて識別できるようにしておく • 例2: DBのSpanには db.query.text attributeに⽣のクエリ⽂字列をいれておく • 例3: HTTPサーバは http.server. response.body.size のHistogram Metricを⼊れておく https://opentelemetry.io/docs/specs/otel/overview/#semantic-conventions

Slide 54

Slide 54 text

4. Zigでつくる SDKミニマルサブセット 66

Slide 55

Slide 55 text

完成品 67 https://github.com/Drumato/opentelemetry-zig

Slide 56

Slide 56 text

ZigでつくるSDKミニマルサブセット 68 デモ

Slide 57

Slide 57 text

ZigでつくるSDKミニマルサブセット 69 デモ

Slide 58

Slide 58 text

OpenTelemetryの仕様 70 まとめ • OpenTelemetryは⾼い拡張性と明確な定義を持つ仕様と実装の集合 • ⾃分たちのユースケースに応じて仕組みを作っていくために、根本技術に詳しくなろう • 上記を実現するためにSDKはよく考えられた設計が採⽤されている • ソフトウェアアーキテクチャのケーススタディとして勉強になる • ミニマルなサブセットを作るのはそこまで難しくない • 仕様が明確なので、それにしたがって作っていけば良い • 公式がサポートしていない⾔語を使っているなら、作ってしまうのも良いかも

Slide 59

Slide 59 text

OpenTelemetryの仕様 71 参考資料 • OpenTelemetry Specification • OTLP Specification • https://github.com/open-telemetry/opentelemetry-go

Slide 60

Slide 60 text

72 We’re hiring! OpenTelemetryだけでなく、ペパボのSREに興味がある⽅