Slide 1

Slide 1 text

toittaに OpenTelemetryを 導入した話 id:cohalz / @cohalz 2025-05-28 Mackerel APM リリースパーティ 1

Slide 2

Slide 2 text

自己紹介 ● こはる(@cohalz) ● 好きなOpenTelemetryの機能 ○ Exponential Histogram 2

Slide 3

Slide 3 text

目次 ● toittaの運用における課題 ● OpenTelemetry導入による変化と展望 ● Next.jsを例にサービス計装の流れを紹介 ○ 時間があれば 3

Slide 4

Slide 4 text

toittaについて ● 2024年7月にリリース ● インタビュー動画をアッ プロードし、生成AIに よってその発話を分析す るサービス 4

Slide 5

Slide 5 text

toittaのシステム構成 ● Google Cloud上に構築されたWebアプリ ○ Cloud Run(Next.js) ○ Cloud SQL(PostgreSQL) ● 生成AIを利用 ○ Vertex AIとAzure OpenAI Service 5

Slide 6

Slide 6 text

6 なぜOTel導入をしたか

Slide 7

Slide 7 text

7 ブラックボックスな 部分が多いサービス

Slide 8

Slide 8 text

サービスの特性 として... ● 入力 ○ ユーザの動画ファイル ● 出力 ○ クラウド/生成AI処理 ● 規約で許可なく 閲覧ができない 8

Slide 9

Slide 9 text

多種多様なエラー・ハルシネーション ● 考えられる原因として... ○ ファイルの形式が正しくない? ○ クラウドの一時的な不調?クォータ制限? ○ リリース起因? ○ ファイルの音質や収音環境の問題? ○ その他考慮してない部分があった? 9

Slide 10

Slide 10 text

これらに対処するために ● 今まではログを中心に運用していた ○ アラートやダッシュボードを作成 ○ 実行時間、エラーの種別、SLOのダッシュボードも ● 改善はしていたものの対応には時間がかかる 10

Slide 11

Slide 11 text

細かいデータが見れていない課題 ● 例1: サービスのレイテンシ ○ 動画アップロードで平均やp95が跳ね上がる ○ この画面が遅いとかの分析が難しい ● 例2: エラーの状況がわかりづらい ○ なんの処理が失敗してどこまで成功しているか ○ エラーから処理時間を見るのも意外と面倒 11

Slide 12

Slide 12 text

状況を改善したいが... ● ログとその活用で手作り対応が手間 ○ 新機能の開発時に対応が漏れる ○ 言語やフレームワークも違うことがある ● その結果対応の属人性が高くなっていた ○ 典型エラーはドキュメントにまとめているが... ○ アラートからログとドキュメントを開く手間 12

Slide 13

Slide 13 text

そんな中 ● MackerelでAPM機能の開発が活発に ○ 社内のサポートとフィードバックができるように ● この機会にOTel導入をすることに ○ ちなみに、チームに知見はない状態からスタート 13

Slide 14

Slide 14 text

14 OTel導入がスタート

Slide 15

Slide 15 text

計装への道のり ● アプリケーションに計装する ● ローカルでcollectorを立てて動作確認 ● サービス上にサイドカー等で導入 ● 扱いやすいように微調整 ● その後手動計装が必要なものにも導入 15

Slide 16

Slide 16 text

16 (実装の話は後半パート もしくは懇親会で)

Slide 17

Slide 17 text

17 OTelのトレース導入 による変化

Slide 18

Slide 18 text

課題は解決できたのか? ● 課題の再掲 ○ 各画面のレイテンシなどわかりたい ○ エラー状況を把握したい ○ 対応をスムーズにしたい 18

Slide 19

Slide 19 text

パスごとの統計情報がわかる 19

Slide 20

Slide 20 text

エラー状況が確認できる 20

Slide 21

Slide 21 text

エラーと対応を一緒に確認できる 21

Slide 22

Slide 22 text

開発の役に立った事例も ● 一部のAPI呼び出しでスロットリングの実装を追加 ● その際に処理時間の95%tileを見て方針を決定 ○ 開発メンバーがMackerelを見ただけで進められた ○ テナント単位などで集計して状況を確認しやすかった声も 22

Slide 23

Slide 23 text

OpenTelemetryの良さ ● 標準の規格に乗ることで ○ 世の中にナレッジ・ツールがあって情報を探しやすい ● 他のサービスに送るといったこともすぐできる ○ いろんなサービスを試しやすい ○ 乗り換えも実装がそのまま使える ○ (Mackerelへのフィードバックも) 23

Slide 24

Slide 24 text

MackerelのAPM機能の良さ ● 必要な情報にすぐ辿り着ける ○ 目的ごとにタブが分かれている ○ 必要な画面や検索欄も最小限で迷いにくい ○ HTTPサーバーとデータベースの統計情報が特に見やすい ○ 課題(エラー)機能はその後の対応までまとめられる ● => 迷いにくく慣れてない開発者もとっつきやすい 24

Slide 25

Slide 25 text

25 OTel導入の今後

Slide 26

Slide 26 text

OTel導入の今後 ● メトリック情報も取れるようにする ● アラートをMackerelに移行 ● トレース情報を強化していく 26

Slide 27

Slide 27 text

メトリック情報も取れるようにする ● 今は短期のメトリックをGoogle Cloud上で確認 ○ クラウドのコンソール上は遅い、期限が短いなど課題 ● Mackerelで確認できるようにしていく ○ 長期のメトリックでキャパシティプランニング ○ トレースから飛べる(逆も)も期待できる 27

Slide 28

Slide 28 text

アラートをMackerelに移行 ● 現在はGoogle Cloud上でアラートを設定 ● Mackerelのアラートに移行したい ○ アラートの閾値や通知周りなど調整がやりやすい ○ 慣れた画面で学習コストを減らせる(開発者も触りやすい) ○ アラートの通知から対応・可視化など自動化も作りやすい 28

Slide 29

Slide 29 text

Tips: アラートにトレースのリンクをつける 29

Slide 30

Slide 30 text

トレースに情報を増やす ● 分散トレーシングを強化 ○ 例えば「こういうファイルの時にこういうエラーにな る」がログを見なくてもわかるように ○ 外部サービス呼び出しの状況を把握する 30

Slide 31

Slide 31 text

LLMのトレース情報 ● LLMに関する情報もトレースに載せる ○ OpenLLMetryを利用? ○ 入出力のトークン数 ○ モデルの変化による振る舞いの変化を追えるように ○ 実際の入出力は閲覧できないのでマスクの必要も 31

Slide 32

Slide 32 text

32 付録: Next.jsを計装する までにやったこと

Slide 33

Slide 33 text

計装への道のり(再掲) ● アプリケーションに計装する ● ローカルでcollectorを立てて動作確認 ● サービス上にサイドカー等で導入 ● 扱いやすいように微調整 ● その後手動計装が必要なものにも導入 33

Slide 34

Slide 34 text

1. アプリケーションに計装する ● 自動計装等で実装する ○ @opentelemetry/auto-instrumentations-node ○ @prisma/instrumentation ● (重要) dynamic importを使って読み込み ○ Next.jsならInstrumentation機能を使う ○ これをしないと計装のコードが読み込まれない 34

Slide 35

Slide 35 text

2. ローカルで確認する ● (重要) 最初はConsoleSpanExporterでログに出す ○ 実装か通信か問題を切り分けやすい ● 手元でcollectorとバックエンドを立てて確認 ○ いきなり送るとトレースやスパン数の爆発も ● 複数のサービスに送って動作確認・切り分け ○ 検証時はjaeger, mackerel, debug(ログ)に送っていた 35

Slide 36

Slide 36 text

3. データを整える ● 送られたデータを見て運用できそうか確認 ○ 正常・異常時に意図したトレースになっているか? ● 本番データに送って大丈夫な量と内容か確認 ○ サンプリング ○ データのマスク 36

Slide 37

Slide 37 text

Tips: collector側で大体できる ● 属性を追加・削除 ○ Attributes Processor ● ルールを決めてサンプリング ○ Tail Sampling Processor ● ロジックを書いて属性等を変換 ○ Transform Processor 37

Slide 38

Slide 38 text

Tips: Transform Processorが高機能 ● OTTLという言語で変換処理を記述 ● 例1: 正規表現で属性をまとめる ○ replace_pattern(span.attributes["http.route"], "_rsc=[a-z0-9]{5}", "_rsc=*****") ● 例2: 特定の条件で属性を削る ○ delete_key(span.attributes, "xxx") where span.attributes["yyy"] == "zzz" 38

Slide 39

Slide 39 text

4. 本番に導入 ● Cloud Runの場合 ○ YAML形式の設定ファイルに移行が必要 ○ https://github.com/GoogleCloudPlatform/openteleme try-cloud-run ● 各サービスのResource Detectionも追加 ○ リビジョンやリージョンなどを埋めてくれる 39

Slide 40

Slide 40 text

5. 計装対象を増やす ● 手動計装 ○ 主にHTTPリクエストベースでないものには手動で ○ 非同期処理にはAsyncHooksContextManagerを利用 ● トレースの伝播 ○ Propagatorを利用してサービス間で伝播 ○ データの渡し方は自由(独自ヘッダで渡すのが良いかも?) 40

Slide 41

Slide 41 text

感想など ● APMって意外と難しくないという印象に ○ 目的の情報にすぐ辿り着ける ○ 開発メンバーと育てていけそう ● 最初にデータを送るまでは大変ではある ○ データが送られてない、まとまってないなど ○ やり方は決まってるのでその後はスムーズ 41