Docs » Splunk Observability Cloud でサポートされているインテグレーション » モバイルおよび Web アプリケーションを Splunk RUM でインストルメンテーションする » Splunk RUM でブラウザベースの Web アプリケーションをインストルメンテーションする » ブラウザベースのウェブアプリケーションを手動でインストルメンテーションする

ブラウザベースのウェブアプリケーションを手動でインストルメンテーションする 🔗

ブラウザ RUM エージェントを使用して、Splunk RUM 用のフロントエンドアプリケーションを手動でインストルメンテーションし、追加のテレメトリを収集したり、個人識別情報 (PII) をサニタイズしたり、ユーザーを識別したりすることができます。以下の API 例では、Splunk RUM 用の手動インストルメンテーションをいくつか紹介しています。

別のベンダー用に作成された手動インストルメンテーションを移行するには、既存の手動インストルメンテーションの移行 を参照してください。ブラウザ RUMのAPIリファレンスについては、ブラウザRUMインストルメンテーションのAPIリファレンス を参照してください。

OpenTelemetry API を使ってアプリケーションをインストルメンテーションする 🔗

フロントエンドのアプリケーションを手動でインストルメンテーションするには、OpenTelemetry API を使います。ブラウザ RUM エージェントは、@opentelemetry/api を使って TraceProvider を自動的に登録します。

OpenTelemetry APIのバージョンを確認する 🔗

アプリケーションを手動でインストルメンテーションするには、使用する @opentelemetry/api のバージョンが、ブラウザ RUM エージェントが使用する @opentelemetry/api のメジャーバージョンと同じでなければなりません。

これを確認するには、インストルメンテーションしたページからブラウザのコンソールで window[Symbol.for('opentelemetry.js.api.1')].version を実行してください。このコマンドは、OpenTelemetry APIのフルバージョンを返します。

スパンを作成する 🔗

次の例は、属性を持つスパンを作成する方法を示しています:

import {trace} from '@opentelemetry/api'

const span = trace.getTracer('searchbox').startSpan('search');
span.setAttribute('searchLength', searchString.length);
// Time passes
span.end();

すべてのスパンにユーザーIDを設定する 🔗

次の例は、ユーザーIDをグローバルに設定する方法を示しています:

SplunkRum.setGlobalAttributes({
   'enduser.id': 'Test User'
});

カスタムイベントの作成 🔗

次の例は、カスタムイベントの作成方法を示しています:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {
   'workflow.name': 'test.module.load'
}
});
// time passes
span.end();

注釈

ブラウザ RUMエージェントのCDNバージョンを使用する際に、コンテンツブロッカーによるロードの問題を回避するために、SplunkRum APIコールの周りに if (window.SplunkRum) チェックを追加します。

個人を特定できる情報(PII)のサニタイズ 🔗

ブラウザ RUMエージェントによって収集されたメタデータは、フロントエンドアプリケーションがそのコードにそのようなデータを注入した場合、個人を特定できる情報(PII)を含む可能性があります。例えば、UIコンポーネントはそのIDにPIIを含む可能性があります。

Splunk RUM 用に収集したデータ内の PII を再編集するには、以下の例のように ブラウザ RUM インストルメンテーションを初期化する際に exporter.onAttributesSerializing 設定を使用します:

SplunkRum.init({
// ...
exporter: {
// You can use the entire span as an optional second argument of the sanitizer if needed
   onAttributesSerializing: (attributes) => ({
      ...attributes,
      'http.url': /secret\=/.test(attributes['http.url']) ? '[redacted]' : attributes['http.url'],
   }),
},
});

注釈

ブラウザ RUMの自動インストルメンテーションは、リクエストのペイロードや POSTボディのサイズ以外のデータを収集したり報告したりしません。

グローバル属性を使用してユーザーメタデータを追加する 🔗

デフォルトでは、ブラウザ RUMエージェントは、トレースをサイトのユーザーに自動的にリンクしません。しかし、トレースをフィルターリングまたはデバッグするために、ユーザーメタデータを収集する必要がある可能性があります。

OpenTelemetry仕様のグローバル属性( enduser.idenduser.role など)をスパンに追加することで、ユーザーを特定することができます。

以下の例は、初期化時にユーザデータにアクセスできるかどうかに応じて、エージェントの初期化時または初期化後に識別メタデータをグローバル属性として追加する方法を示しています:

初期化時に識別メタデータを追加する 🔗

<script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
<script>
SplunkRum.init({
   realm: '<realm>',
   rumAccessToken: '<RUM access token>',
   applicationName: '<application-name>',
   globalAttributes: {
      // The following data is already available
      'enduser.id': 42,
      'enduser.role': 'admin',
   },
});
</script>

初期化後に識別メタデータを追加 🔗

import SplunkRum from '@splunk/otel-web';

const user = await (await fetch('/api/user')).json();
// Spans generated prior to this call don't have user metadata
SplunkRum.setGlobalAttributes({
   'enduser.id': user ? user.id : undefined,
   'enduser.role': user ? user.role : undefined,
});

Splunk APM からサーバートレースコンテキストを追加する 🔗

ブラウザ RUM エージェントは、Server-Timing ヘッダーを通して APM インストルメンテーションから提供されるバックエンドデータを使用して、サーバートレースコンテキストを収集します。ヘッダーを手動で生成したい場合もあるかも知れません。

To create the Server-Timing header manually, provide a Server-Timing header with the name traceparent, where the desc field holds the version, the trace ID, the parent ID, and the trace flag.

次のHTTPヘッダーを考えてみます:

Server-Timing: traceparent;desc="00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"

この例は、以下のデータを含むコンテキストに解決します:

version=00 trace-id=4bf92f3577b34da6a3ce929d0e0e4736
parent-id=00f067aa0ba902b7 trace-flags=01

traceparent ヘッダーの値を生成するときは、それが以下の正規表現にマッチすることを確認します:

00-([0-9a-f]{32})-([0-9a-f]{16})-01

パターンにマッチしない値を持つサーバータイミングヘッダーは自動的に破棄されます。詳しくは、W3C ウェブサイトの Server-Timingtraceparent のドキュメントを参照してください。

注釈

Access-Control-* のような、クロスオリジンリソース共有(CORS)ヘッダーを使用している場合、Server-Timing ヘッダーを読む許可を与える必要がある可能性があります。例: Access-Control-Expose-Headers: Server-Timing

ワークフロー・スパンを作成する 🔗

ワークフロー・スパンでは、スパンにメタデータを追加して、フォームへの入力やショッピングカートのチェックなど、アプリケーションのワークフローで発生するステップを追跡することができます。

ワークフロー・スパンには以下の属性があります:

Name

タイプ

説明

id

文字列

ワークフローインスタンスの固有ID。

name

文字列

現在のワークフローの意味的な名前。

以下のスニペットは、ワークフロー・スパンの作成方法を示しています:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {

   'workflow.name': 'test.module.load'
}
});

// Time passes
span.end();

ワークフロー・スパンのエラー収集を有効にするには、error および error.message 属性を追加します:

import {trace} from '@opentelemetry/api'

const tracer = trace.getTracer('appModuleLoader');
const span = tracer.startSpan('test.module.load', {
attributes: {
   'workflow.name': 'test.module.load',
   'error': true,
   'error.message': 'Custom workflow error message'
}
});

span.end();

シングルページアプリケーションにカスタム・スパンを作成する 🔗

OpenTelemetry API を使って、アプリケーションの構造に特化したカスタム・スパンを作成することができます。例えば、ユーザーが特定のボタンをクリックした時にスパンを生成したり、カスタム通信プロトコルをインストルメンテーションすることができます。

OpenTelemetry API をセットアップする 🔗

npmを使って、現在のバージョンのOpenTelemetry APIパッケージを追加します:

npm install @opentelemetry/api

注釈

OpenTelemetry API のバージョンが、@splunk/otel-web パッケージで使用されている API のメジャーバージョンと一致していることを確認してください。バージョン情報は リリースノート にあります。

カスタム・スパンの作成 🔗

トレーサーを含めることで、カスタム・スパンを作成することができます。例:

import {trace} from '@opentelemetry/api';

// Create a tracer
const tracer = trace.getTracer('my-application', '1.0.0');

// Example of an async/await function
async function processForm(form) {
   const span = tracer.startSpan('process form');

   // Wait for processing to be done
   span.end();
}

// Example of a callback function
function markCompleted(item) {
   const span = tracer.startSpan('item complete');

   processCompletion(item, function() {
      // ... Update item display
      span.end();
   });
}

// Example of hook system provided by another library
router.beforeEach((transition) => {
   transition.span = tracer.startSpan('navigate', {
      attributes: {
         'router.path': transition.path
      }
   });
});

router.afterEach((transition) => {
   if (transition.span) {
      transition.span.end();
   }
});

// For a list of available methods, see the OpenTelemetry API documentation.

生成されたスパンに子スパンを追加するには、コンテキストAPIを使用します。例:

import {trace, context} from '@opentelemetry/api';

// Create a tracer
const tracer = trace.getTracer('my-application', '1.0.0');

async function processForm(form) {
   const span = tracer.startSpan('process form');
   await context.with(trace.setSpan(context.active(), span), async () => {

      await client.send(form); // client.send would create a XHR span using instrumentation

   });
   span.end();
}

注釈

例えば、Promise.then, setTimeout, ... ブロックの中など、直接呼び出されていない子スパンにはコンテキストが伝搬されない可能性があります。この問題を軽減するには、非同期トレースを有効にしてください。非同期トレース設定 を参照してください。

シングルページアプリケーションのフレームワークでエラーを収集する 🔗

独自のエラーインターセプターまたはハンドラを使用するシングルページアプリケーション(SPA)フレームワークからのJavaScriptエラーの収集を有効にするには、ブラウザ RUMエージェントをフレームワークと統合する必要があります。

以下のフレームワーク固有の例では、ブラウザ RUMエージェントをサポートするフレームワークと統合する方法を示します。すべての例は、npmを使用してブラウザ RUMエージェントをインストールしたことを前提としています。npmパッケージ を参照してください。

React 🔗

エラー境界コンポーネントで Splunk RUM エージェント API を使用します:

import React from 'react';
import SplunkRum from '@splunk/otel-web';

class ErrorBoundary extends React.Component {
   componentDidCatch(error, errorInfo) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
      SplunkRum.error(error, errorInfo)
   }

   // Rest of your error boundary component
   render() {
      return this.props.children
   }
}

Vue.js 🔗

Vue errorHandler にcollect関数を追加します。

Vue.jsバージョン3.xの場合は、以下のコードを使用します:

import Vue from 'vue';
import SplunkRum from '@splunk/otel-web';

const app = createApp(App);

app.config.errorHandler = function (error, vm, info) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
   SplunkRum.error(error, info)
}
app.mount('#app')

Vue.jsバージョン2.xの場合は、以下のコードを使用します:

import Vue from 'vue';
import SplunkRum from '@splunk/otel-web';

Vue.config.errorHandler = function (error, vm, info) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
   SplunkRum.error(error, info)
}

Angular 🔗

Angularバージョン2.xの場合は、エラーハンドラモジュールを作成します:

import {NgModule, ErrorHandler} from '@angular/core';
import SplunkRum from '@splunk/otel-web';

class SplunkErrorHandler implements ErrorHandler {
   handleError(error) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
      SplunkRum.error(error, info)
   }
}

@NgModule({
   providers: [
      {
         provide: ErrorHandler,
         useClass: SplunkErrorHandler
      }
   ]
})
class AppModule {}

Angular バージョン 1.x の場合は、exceptionHandler を作成します:

import SplunkRum from '@splunk/otel-web';

angular.module('...')
   .factory('$exceptionHandler', function () {
      return function (exception, cause) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
         SplunkRum.error(exception, cause)
      }
})

Ember.js 🔗

以下の例のように、Ember.onerror フックを設定します:

import Ember from 'ember';
import SplunkRum from '@splunk/otel-web';

Ember.onerror = function(error) {
// To avoid loading issues due to content blockers
// when using the CDN version of the Browser RUM
// agent, add if (window.SplunkRum) checks around
// SplunkRum API calls
   SplunkRum.error(error)
}

This page was last updated on 2023年10月31日.