Next.jsとOpenTelemetry
OTelにはAPIとSDKがある
APIは型定義、SDKにはその実体や実際に計装するために必要なもろもろが入っている
またそれぞれには仕様と実装がある
トレースについて
APIはTracerProvider→Tracer→Spanの三層構造
TracerProviderは共通の設定やTracerの生成、TracerはSpanの生成を行う
TracerProviderにはNodeTracerProviderとWebTracerProviderがある
三層構造はメトリクス、ログでも現れる
MeterProvider→Meter→Instrument
LoggerProvider→Logger→LogRecord
普通はGlobalProviderが1つあり、アプリケーションや計装を行うライブラリはそこからTracer/Meter/Loggerを生成する
TracerProviderではいくつか設定を行う
Resource
テレメトリデータが生成された環境についての情報
サービス名やブラウザの情報が入る
TraceExporter
トレースの出力方法を指定する
JSではデバッグ用のConsoleTraceExporter, テスト用のInMemoryTraceExporter, アプリケーション用のOTLPTraceExporterがある
Exporterについてはメトリクス、ログも同様
SpanProcessor
トレースの出力タイミングを指定する
JSには即座に出力するSimpleSpanProcessor, バッチ処理するBatchSpanProcessorがある
Simple〜はデバッグ、テスト用、Batch〜はアプリ用
Processorについてはログも同様
ContextManager
OTelのコンテキストは異なるサービス間で情報をやりとりする仕組み
利用にはContextManagerが必要
ブラウザJSではZoneContextManagerとStackContextManagerがあり、非同期処理をトレースするにはZoneContextManagerが必要
Node.jsにはAsyncHooksContextManagerとAsyncLocalStorageContextManagerがあり、パフォーマンス、メモリ安全性、既知の不具合からAsyncLocalStorageContextManagerの方が良さそう
Propagator
異なるサービス間でコンテキストを伝播させる
JSにはW3CTraceContextPropagator、W3CBaggagePropagatorがある
トレースの場合はW3CTraceContextPropagatorを使う?
WebTracerProviderの設定は最終的にこうなった
自動計装の設定
Tracerの生成と手動計装
実際には関数を渡したらスパン付きで実行してくれるような関数を作った方が良いだろうOTel Collectorはクロスオリジンになるのでプロキシしておく
メトリクスについて
メトリクスの場合はMetricExporterとMetricReaderの設定をする
JSのMetricReaderには定期的にメトリクスをpushするPeriodicExportingMetricReaderがある
トレースと同様にプロキシする
ログについて
実際にはLoggerのラッパークラスを作った方が良さそう
ここまではブラウザJSの話
ここからNode.jsの話
Next.jsには@vercel/otelというパッケージがあるがこれは不要
中身はNodeSDKを薄くラップしているだけ
Next.jsのデフォルトスパンは便利なので有効にする
Node.js側にはProviderの生成とGlobalProviderへのセットを行うSDKがあるのでこれを利用する
実際の手動計装はブラウザJSと同様
動作確認は以下を利用
ログには対応していないので設定を追加する必要がある
OTel Collectorのログのexportersはloggingしかない
以下をservice.pipelinesに追記
logs:
receivers: [otlp]
processors: [batch]
exporters: [logging]
Ctrl+Cで止めてもテレメトリデータが送られ続けたことがあったので以下があった方が良いかも
ブラウザJSの方は上手い実装が思いつかなかったのと、変な状況にならなかったので不要かも