Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenTelemetry x Datadog APM 多言語環境での計装戦略と実践 / in...

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for mekka mekka
June 04, 2026
43

OpenTelemetry x Datadog APM 多言語環境での計装戦略と実践 / instrumentation-strategies-and-practices-in-multilingual-environment

Avatar for mekka

mekka

June 04, 2026

More Decks by mekka

Transcript

  1. ⾃⼰紹介 ⾒形 親久 Chikahisa Mikata 株式会社ログラス クラウド基盤チーム SREリード SIer にてアプリケーションエンジニアとしてキャリアをスタート。

    ToBのSaaS企業でのSRE組織の⽴ち上げを経て、2024年10⽉より株式会 社ログラスに参画。 現在は共通基盤部にて、開発組織への SRE の推進およびプラットフォー ム開発に取り組んでおり、SRE を⽂化として根付かせることをテーマに 活動しています。
  2. 3

  3. 4

  4. 5

  5. アジェンダ 4⾔語‧マルチサービスの計装を OTel で統⼀した話 • Before: Datadog SDK 時代と転機 •

    判断基準: なぜ OTel を選んだのか • After: OTel 統⼀アーキテクチャの全体像 • 計装の実際: ⾔語ごとに異なる⾃動計装とログ設計 • ハマりどころと学び 今⽇お話しすること
  6. Before Datadog SDK 時代に何が起きていたか 項⽬ Kotlin(メイン) Rust(⼀部) Tracing dd-trace-java +

    @Trace OTel SDK + DD exporter Logging Logback → Fluent Bit → DD ⾃作 Layer で dd.trace_id を⼿動埋込 伝搬⽅式 Datadog 形式(⾃動) Datadog 独⾃ヘッダー(⼿動設定) DD SDK がない⾔語で無理に合わせた結果 • 128bit TraceId → 64bit ⼿動変換 • ログに dd.trace_id をハードコード • Propagator も Datadog 独⾃形式 → アプリがバックエンドの仕様に依存
  7. 転機 ECS/Fargate → EKS へフルリビルド。モノリス → マイクロサービスへ • Go が

    BFF 層として新規参⼊ • TypeScript が LLM 関連サービスとして合流 • 2⾔語 → 4⾔語、サービス数も⼤幅に増加 4⾔語になると何が起きるか: • Datadog SDK がない⾔語がある(Rust)→ SDKベースの計装に統⼀できない • サービス増加でローカル Trace 確認が欲しくなる → DD に送らずに⼿元で確認したい • ⾔語ごとにバラバラな計装 → 品質‧保守性が保てない → 計装基盤もゼロから再設計する判断 ⼀⼤リファクタの決断
  8. 判断基準 なぜ OTel を選んだのか 4⾔語の SDK 対応状況 ⾔語 Datadog SDK

    OTel SDK Go あり あり(最も充実) Kotlin (JVM) あり(成熟) あり(Java agent) Rust なし あり(発展途上) TypeScript (Node) あり あり TypeScript (Browser) RUM のみ 未成熟 4つの判断軸 判断軸 Datadog SDK OpenTelemetry ベンダー依存 アプリ層が DD に依存 アプリ層はベンダ⾮依存 多⾔語対応 ⾔語ごとに SDK 差異あり 全⾔語で同じモデル 標準準拠 Datadog 独⾃形式 W3C / OTLP ローカル開発 DD に送るまで不可 otel-tui で⼿元確認 → アプリ層は OTel で標準化し、Datadog に質の⾼いデータを送る。Datadog をより活かすための判断。
  9. After OTel Browser SDK にはまだない機能を RUM が提供 • セッションリプレイ •

    Core Web Vitals 収集 • ユーザーアクション追跡 しかしトレースは繋がる • RUM SDK v5+ は W3C TraceContext にデフォルト対応 • ブラウザ → バックエンドまで1本のトレースで接続 → OTel で代替できるところは OTel。できないところは Datadog。W3C TraceContext で繋ぐ。 なぜフロントエンドは Datadog RUM なのか
  10. 計装の実際 ― Trace ⾃動計装と⼿動計装 ⾃動計装: ⾔語ランタイムで⽅式が決まる 項⽬ Kotlin (JVM) TypeScript

    Go Rust ⽅式 バイトコード操作 モンキーパッチ contrib wrap Tower + Bridge アプリ変更 不要 不要 必要(定型) 必要(定型) ⼿動計装: 明⽰的スパン⽣成 ⾔語 ⽅式 特徴 Kotlin @WithSpan メソッドに付与するだけでスパン⽣成 Go tracer.Start(ctx, name) Context ベースで明⽰的に開始‧終了 Rust #[instrument] マクロ tracing 経由で OTel Bridge に送信 TypeScript @Trace() デコレーター クラスメソッドにデコレーターで付与 → ⽅式は⾔語ごとに異なるが、出⼒は全て OTLP gRPC に統⼀
  11. 計装の実際 ― Log ログの2経路設計 コンテナ種別 stdout OTel OTLP Datadog への経路

    OTel 対応コンテナ kubectl logs ⽤のみ DD Agent 経由で送信 OTel OTLP のみ OTel ⾮対応 (frontend等) kubectl logs + DD Agent なし stdout 経由
  12. 計装の実際 ― Log 問題: Datadog Agent は全 stdout を⾃動収集する •

    OTel 経由で送信済みのログが stdout 経由でも重複取り込みされる Pod annotation で stdout 収集を除外 ad.datadoghq.com/<name>.logs_exclude: "true" 共通 Helm チャートで⾃動制御 • 全コンテナにデフォルトで logs_exclude: true を付与 • OTel ⾮対応コンテナだけ stdoutContainers で例外宣⾔ → デフォルトで重複を防ぎ、例外だけ明⽰する。開発者が意識せずとも正しくなる設計。 ⼆重取り込み防⽌: Pod annotation と Helm
  13. 計装の実際 ― Log ログ OTLP 経路: Trace と同じ構図が現れる ⾔語 ⽅式

    特徴 Kotlin OTel agent が Logback に appender を⾃動注⼊ コード変更不要 TypeScript PinoInstrumentation が Log Bridge を⾃動パッチ SDK 初期化で有効化 Go slog の multiHandler で stdout と OTLP を並列登録 コードで明⽰的に組⽴ Rust tracing の Registry に TracingBridge を Layer 追加 コードで明⽰的に組⽴ → JVM/Node はランタイムが透過的に割り込み、Go/Rust は明⽰的に組み⽴てる。Trace と同じ構図。
  14. ハマりどころ 背景 • Gradle の shadowJar プラグインで fat JAR を作成

    • クラスパス競合を避けるため grpc-netty-shaded を relocate 何が起きたか • OTel agent はクラス名のパターンで gRPC を検出して⾃動計装する • relocate でパッケージ名が変わり、検出できず⾃動計装がスキップ • gRPC の Trace が出ないがエラーも出ない(サイレント) → gRPC interceptor を⼿動登録して⾃動計装を補完 shadowJar が Trace ⾃動計装を壊す (Kotlin)
  15. ハマりどころ 背景 • W3C TraceContext Level 2 で random flag

    (0x02) が追加 • trace-id がランダム⽣成であることを⽰すフラグ • 仕様上、未知の flag は無視して伝搬すべき (MUST) 何が起きたか • Kotlin の OTel agent は Level 2 準拠 → random flag を付与 • Rust の OTel SDK は Level 2 未対応 → 未知 flag として拒否 • Kotlin → Rust 間で Trace が切断される → upstream の修正を正式リリース前に⼿動で取り込んで解決。多⾔語では SDK 間の仕様追従差に要注意。 W3C TraceContext flags の⾮互換 (Kotlin→Rust)
  16. 学び ⾔語横断の学び 項⽬ Go Kotlin Rust TypeScript SDK 成熟度 最も安定

    Java エコシステム 発展途上 安定 ⾃動計装 contrib wrap Agent バイトコード Tower + Bridge モンキーパッチ ハマりどころ ほぼなし shadowJar W3C flags @WithSpan 未提供 推奨度 OTel ⼀択 OTel agent 推奨 OTel(パッチ覚悟) OTel 推奨 → 計装モデルは統⼀できる。ただし SDK の成熟度差には注意が必要。
  17. まとめ OTel と Datadog を組み合わせる Datadog の価値 具体的に OTLP ネイティブサポート

    設定 1 ⾏で port 4317 有効。変換レイヤー不要 Traces / Logs / Metrics 統合 APM の Trace から関連ログへ1クリック遷移 インフラデータの⾃動集約 Node, Pod, Container メトリクスを Agent が⾃動収集 K8s セキュリティ対応 PSA restricted 準拠の SecurityContext を⾃動 inject レイヤーごとの使い分け •アプリ層は OTel で標準化 → 多⾔語対応‧ローカル開発‧ベンダ⾮依存 •フロントエンドは Datadog RUM → セッションリプレイ‧Core Web Vitals •W3C TraceContext で全レイヤーを1本のトレースに接続 •分析基盤は Datadog → Traces / Logs / Metrics の統合ビュー → OTel はデータの「出し⽅」、Datadog はデータの「使い⽅」。組み合わせることで最⼤の価値が出る。