🔭

OpenTelemetryのClient instrumentation for the browserを試した

2024/12/25に公開

この記事はOpenTelemetry Advent Calendar 2024の20日目の記事です。
https://qiita.com/advent-calendar/2024/opentelemetry

はじめに

OpenTelemetry(Otel)ではブラウザパフォーマンスを計測する機能が開発されています。
2024年12月現在は実験的機能の位置付けになりますが、実際に試して現時点での実装具合を見ることとします。

サンプルコードを動かしてみる

Otel JavaScript SDKの公式ドキュメント内にBrowser向けのサンプルがあるので、それを動かしてみます。
https://opentelemetry.io/docs/languages/js/getting-started/browser/

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Document Load Instrumentation Example</title>
    <base href="/" />
    <meta
      name="traceparent"
      content="00-ab42124a3c573678d4d8b21ba52df3bf-d21f7bc17caa5aba-01"
    />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    Example of using Web Tracer with document load instrumentation with console
    exporter and collector exporter
    <script type="module" src="document-load.js"></script>
  </body>
</html>


index.html

import {
  ConsoleSpanExporter,
  SimpleSpanProcessor,
} from '@opentelemetry/sdk-trace-base';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { registerInstrumentations } from '@opentelemetry/instrumentation';

// Spanをコンソールに出力
const provider = new WebTracerProvider({
  spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
});

provider.register({
  contextManager: new ZoneContextManager(),
});

// ドキュメントの読み込みを計測
registerInstrumentations({
  instrumentations: [new DocumentLoadInstrumentation()],
});


document-load.js

{
  "name": "otel-browser",
  "main": "index.js",
  "dependencies": {
    "@opentelemetry/api": "^1.9.0",
    "@opentelemetry/context-zone": "^1.30.0",
    "@opentelemetry/instrumentation-document-load": "^0.44.0",
    "@opentelemetry/sdk-trace-web": "^1.30.0"
  },
  "devDependencies": {
    "vite": "^6.0.5"
  }
}


package.json

$ npm install
$ npx vite
$ open http://localhost:5173

viteのdevモードを起動してブラウザ開きます。
Chrome devtoolsのConsoleにattributeやeventのオブジェクトが出力されていることが確認できました。

可視化してみる

このままでは情報として利用価値が低いため、可視化を試してみます。
OtelのBrowserに対応したReal User MonitoringのSaaSはまだ少ないですが、その中からGrafana Faroを使ってみます。[1]

https://grafana.com/oss/faro/

前述のdocument-load.jsにコードを追加します。
Grafana FaroにTraceを送信するには専用のパッケージの追加が必要でした。

$ npm i @grafana/faro-web-sdk @grafana/faro-web-tracing
import { trace, context } from '@opentelemetry/api';
import {
  ConsoleSpanExporter,
  SimpleSpanProcessor,
  BatchSpanProcessor,
} from '@opentelemetry/sdk-trace-base';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { initializeFaro } from '@grafana/faro-web-sdk';
import { FaroTraceExporter, FaroSessionSpanProcessor } from '@grafana/faro-web-tracing';

const faro = initializeFaro({
  url: 'https://faro-collector-prod-ap-northeast-0.grafana.net/collect/xxxxxx',
  app: {
    name: "otel-web-demo",
    version: "1.0.0",
    environment: "production",
  }
});

const provider = new WebTracerProvider({
  spanProcessors: [
    new SimpleSpanProcessor(new ConsoleSpanExporter()),
    new FaroSessionSpanProcessor(
      new BatchSpanProcessor(new FaroTraceExporter({ ...faro })),
      faro.metas
    ),
  ],
});

provider.register({
  contextManager: new ZoneContextManager(),
});

registerInstrumentations({
  instrumentations: [new DocumentLoadInstrumentation()],
});

faro.api.initOTEL(trace, context);


document-load.js

先ほどと同様にviteのdevモードを起動してブラウザを開きます。[2]

$ npx vite
$ open http://localhost:5173

Grafana Faraのダッシュボードを開いて、データを確認します。
Core Web Vitalの各種数値と、ユーザーの行動が表示されています。[3]

Otelの利用者にはお馴染みのトレースのウォーターフォールグラフも確認できました。

所感

OpenTelemetryでもブラウザのパフォーマンスを計測できました。
SaaSベンダーが提供するRUMと比較するとまだ機能不足な印象ですが、 Client Instrumentation SIGで活発に議論がされており、これからに期待するフェーズと言えるでしょう。

脚注
  1. 調べた範囲ではHoneycombも対応していましたが、Enterprise Planのみで提供されていたため今回は試すことができませんでした ↩︎

  2. Otelのドキュメントにはバンドラーにparcelを採用していたのですが、@grafana/faro-web-tracingを追加したらエラーになるのでviteに変更しました ↩︎

  3. 今回はドキュメントの読み込みだけですが、Otelのパッケージを追加することでClickやfetchなどのイベントも計測できます。 ↩︎

GitHubで編集を提案

Discussion