Source

SDK version


概要

RUM によって収集されたデータおよびコンテキストを、次のニーズをサポートするために変更する方法は、さまざまあります。

  • 個人を特定できる情報などの機密データを保護します。
  • サポートを支援するために、ユーザーセッションをそのユーザーの内部 ID に接続します。
  • データをサンプリングすることにより、収集する RUM データの量を削減します。
  • データの送信元について、デフォルトの属性が提供するものよりも多くのコンテキストを提供します。

デフォルトの RUM ビュー名をオーバーライドする

バージョン 2.17.0 からは、trackViewsManually オプションでビューイベントを手動で追跡することにより、ビュー名を追加して、チームが所有する専用サービスに割り当てることができます。

RUM ブラウザ SDK は、ユーザーが訪れた新しいページごとにビューイベントを自動生成します。また、ページ URL が変更された場合 (シングルページアプリケーションの場合) にも生成されます。ビュー名は現在のページ URL から計算され、可変 ID は自動的に削除されます。少なくとも 1 つの数字を含むパスセグメントは、可変 ID と見なされます。たとえば、/dashboard/1234/dashboard/9a/dashboard/? になります。

デフォルトの RUM ビュー名をオーバーライドするには、次のようにします。

  1. RUM ブラウザ SDK を初期化する際に、trackViewsManually を true に設定します。

    import { datadogRum } from '@datadog/browser-rum';
    
    datadogRum.init({
          ...,
          trackViewsManually: true,
          ...
    });
    
    window.DD_RUM.onReady(function() {
          window.DD_RUM.init({
             ...,
             trackViewsManually: true,
             ...
          })
    })
    
    window.DD_RUM &&
          window.DD_RUM.init({
             ...,
             trackViewsManually: true,
             ...
          });
    
  2. 新しいページまたはルート変更 (シングルページアプリケーションの場合) のたびにビューを開始する必要があります。ビューが開始されると、RUM データが収集されます。

サービス名とバージョンを定義する

バージョン 4.13.0 以降は、関連するサービス名とバージョンもオプションとして定義できます。

  • ビュー名: デフォルトはページの URL パスです。
  • サービス: デフォルトは、RUM アプリケーションの作成時に指定されたデフォルトのサービスです。
  • バージョン: デフォルトは、RUM アプリケーションの作成時に指定されたデフォルトのバージョンです。

ページビューを手動で追跡する

次の例は、RUM アプリケーションの checkout ページでページビューを手動で追跡します。サービスとバージョンはどちらも指定できません。

datadogRum.startView('checkout')
window.DD_RUM.onReady(function() {
        window.DD_RUM.startView('checkout')
})
window.DD_RUM && window.DD_RUM.startView('checkout')

次の例は、RUM アプリケーションの checkout ページでページビューを手動で追跡します。ビュー名には checkout を使用し、purchase サービスをバージョン 1.2.3 に関連付けます。

datadogRum.startView({
  name: 'checkout',
  service: 'purchase',
  version: '1.2.3'
})
window.DD_RUM.onReady(function() {
  window.DD_RUM.startView({
    name: 'checkout',
    service: 'purchase',
    version: '1.2.3'
  })
})
window.DD_RUM && window.DD_RUM.startView({
  name: 'checkout',
  service: 'purchase',
  version: '1.2.3'
})
  • コンテキスト: バージョン 5.28.0 から、ビューおよびその子イベントにコンテキストを追加できます。

次の例は、RUM アプリケーションの checkout ページでページビューを手動で追跡します。ビュー名には checkout を使用し、purchase サービスをバージョン 1.2.3 に関連付けます。

datadogRum.startView({
     name: 'checkout',
     service: 'purchase',
     version: '1.2.3',
     context: {
         payment: 'Done'
     },
})
window.DD_RUM.onReady(function() {
   window.DD_RUM.startView({
         name: 'checkout',
         service: 'purchase',
         version: '1.2.3',
         context: {
             payment: 'Done'
         },
   })
})
window.DD_RUM && window.DD_RUM.startView({
     name: 'checkout',
     service: 'purchase',
     version: '1.2.3',
     context: {
         payment: 'Done'
     },
})

React ルーターのインスツルメンテーション

React、Angular、Vue、またはその他のフロントエンドフレームワークを使用している場合、Datadog はフレームワークルーターレベルで startView ロジックを実装することをお勧めします。

デフォルトの RUM ビュー名をオーバーライドして、React アプリケーションで定義したビュー名と一致させるには、以下の手順に従う必要があります。

: これらの手順は、React Router v6 ライブラリに固有のものです。

  1. 前述のようにして、RUM ブラウザ SDK を初期化する際に、trackViewsManuallytrue に設定します。

  2. ルート変更ごとのビューを開始します。

    import { matchRoutes, useLocation } from 'react-router-dom';
    import { routes } from 'path/to/routes';
    import { datadogRum } from "@datadog/browser-rum";
    
    export default function App() {
       // Track every route change with useLocation API
       let location = useLocation();
    
       useEffect(() => {
       const routeMatches = matchRoutes(routes, location.pathname);
       const viewName = routeMatches && computeViewName(routeMatches);
       if (viewName) {
          datadogRum.startView({name: viewName});
       }
       }, [location.pathname]);
    
       ...
    }
    
    // Compute view name out of routeMatches
    function computeViewName(routeMatches) {
       let viewName = "";
       for (let index = 0; index < routeMatches.length; index++) {
       const routeMatch = routeMatches[index];
       const path = routeMatch.route.path;
       // Skip pathless routes
       if (!path) {
          continue;
       }
    
       if (path.startsWith("/")) {
          // Handle absolute child route paths
          viewName = path;
       } else {
          // Handle route paths ending with "/"
          viewName += viewName.endsWith("/") ? path : `/${path}`;
       }
       }
    
       return viewName || '/';
    }
    
    import { matchRoutes, useLocation } from 'react-router-dom';
    import { routes } from 'path/to/routes';
    
    export default function App() {
       // Track every route change with useLocation API
       let location = useLocation();
    
       useEffect(() => {
       const routeMatches = matchRoutes(routes, location.pathname);
       const viewName = routeMatches && computeViewName(routeMatches);
       if (viewName) {
          DD_RUM.onReady(function() {
             DD_RUM.startView({name: viewName});
          });
       }
       }, [location.pathname]);
    
       ...
    }
    
    // Compute view name out of routeMatches
    function computeViewName(routeMatches) {
       let viewName = "";
       for (let index = 0; index < routeMatches.length; index++) {
       const routeMatch = routeMatches[index];
       const path = routeMatch.route.path;
       // Skip pathless routes
       if (!path) {
          continue;
       }
    
       if (path.startsWith("/")) {
          // Handle absolute child route paths
          viewName = path;
       } else {
          // Handle route paths ending with "/"
          viewName += viewName.endsWith("/") ? path : `/${path}`;
       }
       }
    
       return viewName || '/';
    }
    
    import { matchRoutes, useLocation } from 'react-router-dom';
    import { routes } from 'path/to/routes';
    
    export default function App() {
       // Track every route change with useLocation API
       let location = useLocation();
    
       useEffect(() => {
       const routeMatches = matchRoutes(routes, location.pathname);
       const viewName = routeMatches && computeViewName(routeMatches);
       if (viewName) {
          window.DD_RUM &&
             window.DD_RUM.startView({name: viewName});
       }
       }, [location.pathname]);
    
       ...
    }
    
    // Compute view name out of routeMatches
    function computeViewName(routeMatches) {
       let viewName = "";
       for (let index = 0; index < routeMatches.length; index++) {
       const routeMatch = routeMatches[index];
       const path = routeMatch.route.path;
       // Skip pathless routes
       if (!path) {
          continue;
       }
    
       if (path.startsWith("/")) {
          // Handle absolute child route paths
          viewName = path;
       } else {
          // Handle route paths ending with "/"
          viewName += viewName.endsWith("/") ? path : `/${path}`;
       }
       }
    
       return viewName || '/';
    }
    

ビュー名を設定する

現在のビューの名前を更新するには、setViewName(name: string) を使用します。これにより、新しいビューを開始することなく、ビュー表示中にビュー名を変更できます。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.setViewName('<VIEW_NAME>');

// Code example
datadogRum.setViewName('Checkout');
window.DD_RUM.onReady(function() {
   window.DD_RUM.setViewName('<VIEW_NAME>');
})

// Code example
window.DD_RUM.onReady(function() {
   window.DD_RUM.setViewName('Checkout');
})
window.DD_RUM && window.DD_RUM.setViewName('<VIEW_NAME>');

// Code example
window.DD_RUM && window.DD_RUM.setViewName('Checkout');

: ビュー名を変更すると、そのメソッドが呼び出された後、当該時点以降のビューおよびその子イベントに影響します。

詳しくは、ブラウザモニタリングの設定をご覧ください。

RUM データを強化および制御する

RUM ブラウザ SDK は RUM イベントをキャプチャし、主要な属性を設定します。コールバック関数 beforeSend を使用することにより、RUM SDK によって収集されたすべてのイベントを Datadog に送信する前に、それにアクセスすることができます。

RUM イベントをインターセプトすると、次のことが可能になります。

  • 追加のコンテキスト属性で RUM イベントを強化する
  • RUM イベントを変更してコンテンツを変更するか、機密性の高いシーケンスを編集する (編集可能なプロパティのリストを参照)
  • 選択した RUM イベントを破棄する

バージョン 2.13.0 以降、beforeSend は 2 つの引数を取ります。RUM ブラウザ SDK によって生成された event と、RUM イベントの作成をトリガーした context です。

function beforeSend(event, context)

潜在的な context 値は次のとおりです。

RUM イベントタイプコンテキスト
ビュー場所
アクションイベント とハンドリングスタック
リソース (XHR)XMLHttpRequestPerformanceResourceTiming、およびハンドリングスタック
リソース (フェッチ)リクエスト応答PerformanceResourceTiming、およびハンドリングスタック
リソース (その他)PerformanceResourceTiming
エラーエラー
Long TaskPerformanceLongTaskTiming

詳細については、RUM データの強化と制御ガイドを参照してください。

RUM イベントを強化する

イベントには、グローバルコンテキスト API または Feature Flag データ収集で追加された属性に加えて、追加のコンテキスト属性を設定できます。たとえば、RUM リソースイベントに、フェッチ応答オブジェクトから抽出したデータのタグを付けます。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event, context) => {
      // collect a RUM resource's response headers
      if (event.type === 'resource' && event.resource.type === 'fetch') {
            event.context.responseHeaders = Object.fromEntries(context.response.headers)
      }
      return true
   },
   ...
});
window.DD_RUM.onReady(function() {
   window.DD_RUM.init({
      ...,
      beforeSend: (event, context) => {
            // collect a RUM resource's response headers
            if (event.type === 'resource' && event.resource.type === 'fetch') {
               event.context.responseHeaders = Object.fromEntries(context.response.headers)
            }
            return true
      },
      ...
   })
})
window.DD_RUM &&
   window.DD_RUM.init({
      ...,
      beforeSend: (event, context) => {
            // collect a RUM resource's response headers
            if (event.type === 'resource' && event.resource.type === 'fetch') {
               event.context.responseHeaders = Object.fromEntries(context.response.headers)
            }
            return true
      },
      ...
   });

ユーザーが複数のチームに所属している場合は、グローバルコンテキスト API を呼び出す際に、Key-Value ペアを追加してください。

RUM Browser SDK は event.context 以外に追加された属性を無視します。

機能フラグで RUM イベントをリッチ化する

フィーチャーフラグで RUM イベントデータを強化することにより、パフォーマンスモニタリングについての追加のコンテキストや可視性を得ることができます。これにより、どのユーザーに特定のユーザーエクスペリエンスが表示されるかを判別でき、またそれがユーザーのパフォーマンスに悪影響を与えているかどうかを判断することができます。

RUM イベントのコンテンツを変更

たとえば、Web アプリケーションの URL からメールアドレスを編集するには

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event) => {
      // remove email from view url
      event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
   },
   ...
});
window.DD_RUM.onReady(function() {
   window.DD_RUM.init({
      ...,
      beforeSend: (event) => {
            // remove email from view url
            event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
      },
      ...
   })
})
window.DD_RUM &&
   window.DD_RUM.init({
      ...,
      beforeSend: (event) => {
            // remove email from view url
            event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
      },
      ...
   });

次のイベントプロパティを更新できます。

属性説明
view.url文字列アクティブな Web ページの URL。
view.referrer文字列現在リクエストされているページへのリンクがたどられた前のウェブページの URL。
view.name文字列現在のビューの名前。
view.performance.lcp.resource_url文字列Largest Contentful Paint のリソース URL。
service文字列アプリケーションのサービス名。
version文字列アプリケーションのバージョン。たとえば: 1.2.3、6c44da20、または2020.02.13。
action.target.name文字列ユーザーがやり取りした要素。自動的に収集されたアクションのみ。
error.message文字列エラーについて簡潔にわかりやすく説明する 1 行メッセージ。
error.stack文字列スタックトレースまたはエラーに関する補足情報。
error.resource.url文字列エラーをトリガーしたリソース URL。
resource.url文字列リソース URL。
long_task.scripts.source_url文字列スクリプト リソース URL
long_task.scripts.invoker文字列スクリプトがどのように呼び出されたかを示す意味のある名前
contextオブジェクトGlobal Context APIView Context API、またはイベントを手動で生成する際 (addErroraddAction) に追加される属性。

RUM ブラウザ SDK は、上記のリストにないイベントプロパティに加えられる変更を無視します。イベントプロパティについて詳しくは、RUM ブラウザ SDK GitHub リポジトリを参照してください。

: 他のイベントとは異なり、ビューのイベントはライフサイクル中に発生する更新を反映するために Datadog に複数回送信されます。新しいビューがアクティブな間も、過去のビューイベントに関する更新を送信することが可能です。Datadog では、ビューイベントの内容を変更する際にこの動作に注意することが推奨されています。

beforeSend: (event) => {
    // discouraged, as the current view name could be applied to both the active view and the previous views
    event.view.name = getCurrentViewName()

    // recommended
    event.view.name = getViewNameForUrl(event.view.url)
}

RUM イベントを破棄

beforeSend API で、false を返し RUM イベントを破棄します。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event) => {
      if (shouldDiscard(event)) {
         return false
      }
      ...
   },
   ...
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        beforeSend: (event) => {
            if (shouldDiscard(event)) {
                return false
            },
            ...
        },
        ...
    })
})
window.DD_RUM &&
    window.DD_RUM.init({
        ...,
        beforeSend: (event) => {
            if (shouldDiscard(event)) {
                return false
            }
            ...
        },
        ...
    });

: ビューイベントは破棄できません。

ユーザーセッション

RUM セッションにユーザー情報を追加することで、以下が可能になります。

  • 特定のユーザーのジャーニーをたどる
  • エラーの影響を最も受けているユーザーを把握する
  • 最も重要なユーザーのパフォーマンスを監視する
RUM UI 内のユーザー API

バージョン6.4.0 以上では、以下の属性が利用可能です。

属性必須説明
usr.id文字列Yes一意のユーザー識別子。
usr.name文字列NoRUM UI にデフォルトで表示されるユーザーフレンドリーな名前。
usr.email文字列Noユーザーのメール。ユーザー名が存在しない場合に RUM UI に表示されます。Gravatars を取得するためにも使用されます。

以下の属性は、バージョン6.4.0 より前はオプションでしたが、Datadog では少なくとも 1 つを指定することが強く推奨されています。たとえば、一部のデフォルト RUM ダッシュボードで関連データを表示する場合、クエリの一部として usr.id に依存するため、セッションにユーザー ID を設定する必要があります。

属性説明
usr.id文字列一意のユーザー識別子。
usr.name文字列RUM UI にデフォルトで表示されるユーザーフレンドリーな名前。
usr.email文字列ユーザーのメール。ユーザー名が存在しない場合に RUM UI に表示されます。Gravatars を取得するためにも使用されます。

: usr.name が設定されていない場合は、usr.emailusr.id が定義されていても、RUM UI には 'Public User' と表示されます。

推奨される属性に加えて、追加属性を加えることでフィルタリング機能を向上させてください。たとえば、ユーザープランや所属するユーザーグループに関する情報を追加します。

ユーザーセッションオブジェクトに変更を加えた場合、変更後に収集されるすべての RUM イベントには、更新された情報が含まれます。

: ログアウトのようにユーザーセッション情報を削除すると、ログアウト前の最後のビューではユーザー情報が保持されますが、それ以降のビューやセッションレベルでは、セッションデータは最後のビューの値を使用するため保持されません。

ユーザーセッションを特定する

datadogRum.setUser(<USER_CONFIG_OBJECT>)

datadogRum.setUser({
    id: '1234',
    name: 'John Doe',
    email: 'john@doe.com',
    plan: 'premium',
    ...
})
window.DD_RUM.onReady(function() {
    window.DD_RUM.setUser({
        id: '1234',
        name: 'John Doe',
        email: 'john@doe.com',
        plan: 'premium',
        ...
    })
})
window.DD_RUM && window.DD_RUM.setUser({
    id: '1234',
    name: 'John Doe',
    email: 'john@doe.com',
    plan: 'premium',
    ...
})

ユーザーセッションにアクセスする

datadogRum.getUser()

datadogRum.getUser()
window.DD_RUM.onReady(function() {
    window.DD_RUM.getUser()
})
window.DD_RUM && window.DD_RUM.getUser()

ユーザーセッションプロパティの追加/オーバーライド

datadogRum.setUserProperty('<USER_KEY>', <USER_VALUE>)

datadogRum.setUserProperty('name', 'John Doe')
window.DD_RUM.onReady(function() {
    window.DD_RUM.setUserProperty('name', 'John Doe')
})
window.DD_RUM && window.DD_RUM.setUserProperty('name', 'John Doe')

ユーザーセッションプロパティを削除する

datadogRum.removeUserProperty('<USER_KEY>')

datadogRum.removeUserProperty('name')
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeUserProperty('name')
})
window.DD_RUM && window.DD_RUM.removeUserProperty('name')

ユーザーセッションプロパティをクリアする

datadogRum.clearUser()

datadogRum.clearUser()
window.DD_RUM.onReady(function() {
    window.DD_RUM.clearUser()
})
window.DD_RUM && window.DD_RUM.clearUser()

アカウント

ユーザーを別のセットに分類するには、アカウントの概念を使用します。

次の属性を利用できます:

属性必須説明
account.id文字列Yes一意のアカウント識別子。
account.name文字列NoRUM UI にデフォルトで表示されるユーザーフレンドリーなアカウント。

アカウントを特定する

datadogRum.setAccount(<ACCOUNT_CONFIG_OBJECT>)

datadogRum.setAccount({
    id: '1234',
    name: 'My Company Name',
    ...
})
window.DD_RUM.onReady(function() {
    window.DD_RUM.setAccount({
        id: '1234',
        name: 'My Company Name',
        ...
    })
})
window.DD_RUM && window.DD_RUM.setAccount({
    id: '1234',
    name: 'My Company Name',
    ...
})

アカウントにアクセスする

datadogRum.getAccount()

datadogRum.getAccount()
window.DD_RUM.onReady(function() {
    window.DD_RUM.getAccount()
})
window.DD_RUM && window.DD_RUM.getAccount()

アカウントプロパティの追加/オーバーライド

datadogRum.setAccountProperty('<ACCOUNT_KEY>', <ACCOUNT_VALUE>)

datadogRum.setAccountProperty('name', 'My Company Name')
window.DD_RUM.onReady(function() {
    window.DD_RUM.setAccountProperty('name', 'My Company Name')
})
window.DD_RUM && window.DD_RUM.setAccountProperty('name', 'My Company Name')

アカウントプロパティを削除する

datadogRum.removeAccountProperty('<ACCOUNT_KEY>')

datadogRum.removeAccountProperty('name')
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeAccountProperty('name')
})
window.DD_RUM && window.DD_RUM.removeAccountProperty('name')

アカウントプロパティをクリアする

datadogRum.clearAccount()

datadogRum.clearAccount()
window.DD_RUM.onReady(function() {
    window.DD_RUM.clearAccount()
})
window.DD_RUM && window.DD_RUM.clearAccount()

サンプリング

デフォルトの場合、収集されたセッションの数にはサンプリングが適用されません。収集されたセッションの数に対して相対サンプリング (パーセント) を適用するには、RUM 初期化時に sessionSampleRate パラメーターを使用します。

下記の例では、RUM アプリケーションの全セッションの 90% のみを収集します。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
    applicationId: '<DATADOG_APPLICATION_ID>',
    clientToken: '<DATADOG_CLIENT_TOKEN>',
    site: '<DATADOG_SITE>',
    sessionSampleRate: 90,
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        clientToken: '<CLIENT_TOKEN>',
        applicationId: '<APPLICATION_ID>',
        site: '<DATADOG_SITE>',
        sessionSampleRate: 90,
    })
})
window.DD_RUM &&
    window.DD_RUM.init({
        clientToken: '<CLIENT_TOKEN>',
        applicationId: '<APPLICATION_ID>',
        site: '<DATADOG_SITE>',
        sessionSampleRate: 90,
    });

サンプルとして抽出したセッションでは、すべてのページビューとそのセッションに紐付くテレメトリーは収集されません。

GDPR、CCPA、および同様の規制に準拠するために、RUM Browser SDK では初期化時に追跡に関する同意を提供できます。追跡に関する同意について詳しくは、データセキュリティを参照してください。

trackingConsent の初期化パラメーターは次のいずれかの値で示されます。

  1. "granted" (デフォルト): RUM Browser SDK はデータの収集を開始し、それをDatadog に送信します。
  2. "not-granted": RUM Browser SDK はデータを収集しません。

RUM Browser SDK の初期化後に追跡同意値を変更するには、setTrackingConsent() API 呼び出しを使用します。RUM Browser SDK は新しい値に応じて動作を変更します。

  • "granted" から "not-granted" に変更すると、RUM セッションは停止し、データは Datadog に送信されなくなります。
  • "not-granted" から "granted" に変更すると、以前のセッションがアクティブでない場合、新しい RUM セッションが作成され、データ収集が再開されます。

この状態はタブ間で同期されず、ナビゲーション間で永続化されません。RUM Browser SDK の初期化時や、setTrackingConsent() を使用して、ユーザーの決定を提供するのはユーザーの責任です。

setTrackingConsent()init() の前に使用された場合、指定された値が初期化パラメーターよりも優先されます。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
    ...,
    trackingConsent: 'not-granted'
});

acceptCookieBannerButton.addEventListener('click', function() {
    datadogRum.setTrackingConsent('granted');
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        trackingConsent: 'not-granted'
    });
});

acceptCookieBannerButton.addEventListener('click', () => {
    window.DD_RUM.onReady(function() {
        window.DD_RUM.setTrackingConsent('granted');
    });
});
window.DD_RUM && window.DD_RUM.init({
  ...,
  trackingConsent: 'not-granted'
});

acceptCookieBannerButton.addEventListener('click', () => {
    window.DD_RUM && window.DD_RUM.setTrackingConsent('granted');
});

ビューコンテキスト

バージョン 5.28.0 以降、ビューイベントのコンテキストは変更可能です。コンテキストは現在のビューにのみ追加でき、その子イベント (actionerrortiming など) が startViewsetViewContext、および setViewContextProperty 関数を使用して設定されます。

コンテキストを使用してビューを開始

オプションとして、startView のオプション を使用することにより、ビュー開始時にコンテキストを定義できます。

ビューコンテキストを追加

setViewContextProperty(key: string, value: any) API を使用して、RUM ビューイベントおよび対応する子イベントのコンテキストを拡充または変更します。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
datadogRum.setViewContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContextProperty('activity', {
        hasPaid: true,
        amount: 23.42
    });
})
window.DD_RUM && window.DD_RUM.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
window.DD_RUM && window.DD_RUM.setViewContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});

ビューコンテキストを置き換える

setViewContext(context: Context) API を使用して、RUM ビューイベントおよび対応する子イベントのコンテキストを置換します。

import { datadogRum } from '@datadog/browser-rum';
datadogRum.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
datadogRum.setViewContext({
    originalUrl: 'shopist.io/department/chairs',
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContext({
      originalUrl: 'shopist.io/department/chairs',
    })
})
window.DD_RUM &&
    window.DD_RUM.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
window.DD_RUM &&
    window.DD_RUM.setViewContext({
        originalUrl: 'shopist.io/department/chairs',
    });

エラー コンテキスト

dd_context を使用したローカル エラー コンテキストの添付

エラーをキャプチャする際、エラー生成時点で追加のコンテキストを提供できます。addError() APIを通じて追加情報を渡す代わりに、dd_context プロパティをエラーインスタンスに直接添付できます。RUM Browser SDK がこのプロパティを自動的に検出し、最終的なエラーイベントコンテキストに統合します。

const error = new Error('Something went wrong')
error.dd_context = { component: 'Menu', param: 123, }
throw error

グローバルコンテキスト

グローバルコンテキストプロパティを追加する

RUM を初期化した後、setGlobalContextProperty(key: string, value: any) API を使用してアプリケーションから収集したすべての RUM イベントにコンテキストを追加します。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.setGlobalContextProperty('<CONTEXT_KEY>', <CONTEXT_VALUE>);

// Code example
datadogRum.setGlobalContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContextProperty('activity', {
        hasPaid: true,
        amount: 23.42
    });
})
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});

グローバルコンテキストプロパティを削除する

以前に定義したグローバルコンテキストプロパティを削除することができます。

import { datadogRum } from '@datadog/browser-rum';
datadogRum.removeGlobalContextProperty('<CONTEXT_KEY>');

// Code example
datadogRum.removeGlobalContextProperty('codeVersion');
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeGlobalContextProperty('codeVersion');
})
window.DD_RUM &&
    window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');

// Code example
window.DD_RUM &&
    window.DD_RUM.removeGlobalContextProperty('codeVersion');

グローバルコンテキストを置換

setGlobalContext(context: Context) API を使用してすべての RUM イベントのデフォルトコンテキストを置換します。

import { datadogRum } from '@datadog/browser-rum';
datadogRum.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
datadogRum.setGlobalContext({
    codeVersion: 34,
});
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContext({
        codeVersion: 34,
    })
})
window.DD_RUM &&
    window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
window.DD_RUM &&
    window.DD_RUM.setGlobalContext({
        codeVersion: 34,
    });

グローバルコンテキストをクリアする

グローバルコンテキストをクリアするには、clearGlobalContext を使用します。

import { datadogRum } from '@datadog/browser-rum';

datadogRum.clearGlobalContext();
window.DD_RUM.onReady(function() {
  window.DD_RUM.clearGlobalContext();
});
window.DD_RUM && window.DD_RUM.clearGlobalContext();

グローバルコンテキストを読み取る

RUM を初期化したら、getGlobalContext() API を使用してグローバルコンテキストを読み取ります。

import { datadogRum } from '@datadog/browser-rum';

const context = datadogRum.getGlobalContext();
window.DD_RUM.onReady(function() {
  const context = window.DD_RUM.getGlobalContext();
});
const context = window.DD_RUM && window.DD_RUM.getGlobalContext();

コンテキストのライフサイクル

デフォルトでは、グローバルコンテキストとユーザーコンテキストは現在のページメモリに格納されます。つまり、これらは

  • ページのフルリロード後に保持されません
  • 同じセッションの異なるタブまたはウィンドウ間で共有されません

セッションのすべてのイベントに追加するには、すべてのページにアタッチする必要があります。

バージョン 4.49.0 で storeContextsAcrossPages 構成オプションが導入されたことにより、これらのコンテキストは localStorage に保存でき、以下の動作が可能になります。

  • フルリロード後にコンテキストが保持される
  • 同じオリジンで開かれたタブ間でコンテキストが同期される

しかし、この機能にはいくつかの制限があります。

  • localStorage に格納されたデータはユーザーセッションよりも長続きするため、これらのコンテキストで個人を特定できる情報 (PII) を設定することは推奨されません
  • この機能は trackSessionAcrossSubdomains のオプションと互換性がありません。なぜなら localStorage のデータは同じオリジン間 (login.site.com ≠ app.site.com) でしか共有されないからです
  • localStorage はオリジンごとに 5 MiB に制限されているため、ローカルストレージに格納されているアプリケーション固有のデータ、 Datadog コンテキスト、およびその他のサードパーティデータは、問題を避けるためにこの制限内に収める必要があります

内部コンテキスト

Datadog ブラウザ RUM SDK が初期化されると、SDK の内部コンテキストにアクセスすることができます。これにより、SDK が内部で使用するセッション ID やアプリケーションの詳細などのコア識別子とメタデータが提供されます。

以下の属性を調べることができます。

属性説明
application_idアプリケーションの ID。
session_idセッションの ID。
user_actionアクション ID を含むオブジェクト (アクションが見つからなかった場合は未定義)。
ビュー現在のビューイベントに関する詳細を含むオブジェクト。

詳細については、RUM ブラウザデータ収集を参照してください。

{
  application_id : "xxx",
  session_id : "xxx",
  user_action: { id: "xxx" },
  view : {
    id : "xxx",
    referrer : "",
    url: "http://localhost:8080/",
    name: "homepage"
  }
}

オプションで、startTime パラメーターを使用して、特定の時間のコンテキストを取得することができます。パラメーターが省略された場合、現在のコンテキストが返されます。

getInternalContext (startTime?: 'number' | undefined)
import { datadogRum } from '@datadog/browser-rum'

datadogRum.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
window.DD_RUM.onReady(function () {
  window.DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
})
window.DD_RUM && window.DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }

マイクロフロントエンド

RUM Browser SDKは、serviceversion の属性を使用して特定のマイクロフロントエンドにイベントを割り当てることにより、マイクロフロントエンドアーキテクチャをサポートします。単一の RUM SDK インスタンスは、シェルレベルで実行されます。イベントは serviceversion によってセグメント化されるので、チームはダッシュボードをフィルタリングし、アラートを設定し、マイクロフロントエンドごとのパフォーマンスを追跡することができます。

Datadog には、RUM イベントをマイクロフロントエンドに割り当てるために、以下の2つのアプローチが用意されています。

  1. 自動割り当て: ソースコードコンテキストを取り込むビルドプラグインを使用し、手動のスタックトレース解析を排除します。
  2. 手動割り当て: beforeSend コールバックを使用してスタックトレースを解析し、サービス情報を抽出します。

自動サービスとバージョン割り当て

このアプローチでは、ビルドプラグインを使用してソースコードコンテキストをバンドルに取り込み、RUM SDK が自動的に読み取って適切な service および version によりイベントを強化します。

前提条件とサポートされているセットアップ

セットアップガイド

ステップ 1 - マイクロフロントエンドごとにビルドプラグインを構成する

各マイクロフロントエンドのビルド構成で、ソースコードコンテキストの取り込みを有効にします。

const { datadogWebpackPlugin } = require('@datadog/webpack-plugin');

module.exports = {
    plugins: [
        new datadogWebpackPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
import { datadogVitePlugin } from '@datadog/vite-plugin';

export default {
    plugins: [
        datadogVitePlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
const { datadogEsbuildPlugin } = require('@datadog/esbuild-plugin');

require('esbuild').build({
    plugins: [
        datadogEsbuildPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
});
import { datadogRollupPlugin } from '@datadog/rollup-plugin';

export default {
    plugins: [
        datadogRollupPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
const { datadogRspackPlugin } = require('@datadog/rspack-plugin');

module.exports = {
    plugins: [
        new datadogRspackPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};

ステップ2 - シェルレベルで Browser SDK をセットアップする

シェルアプリケーション (メインエントリポイント) でブラウザのモニタリングをセットアップします。Browser SDK は、コンテキストマップからの serviceversion を使用することにより、RUM イベント (エラー、カスタムアクション、XHR/Fetch リソース、長時間タスク、バイタル) を自動的に機能拡張します。

マイクロフロントエンドに一致しないイベントは、シェルレベルのサービスおよびバージョンにフォールバックします。

ステップ 3 - Datadog でマイクロフロントエンドデータを探索する

サービスとバージョンの手動割り当て

beforeSend プロパティで、サービスとバージョンのプロパティをオーバーライドできます。context.handlingStack プロパティを使用すれば、イベントの発生元を特定する助けになります。

import { datadogRum } from '@datadog/browser-rum';

const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

datadogRum.init({
    ...,
    beforeSend: (event, context) => {
        const stack = context?.handlingStack || event?.error?.stack;
        const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

        if (service && version) {
          event.service = service;
          event.version = version;
        }

        return true;
    },
});
const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        beforeSend: (event, context) => {
            const stack = context?.handlingStack || event?.error?.stack;
            const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

            if (service && version) {
                event.service = service;
                event.version = version;
            }

            return true;
        },
    });
});
const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

window.DD_RUM && window.DD_RUM.init({
    ...,
    beforeSend: (event, context) => {
        const stack = context?.handlingStack || event?.error?.stack;
        const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

        if (service && version) {
          event.service = service;
          event.version = version;
        }

        return true;
    },
});

正規表現は、アプリケーションのファイルパス構造と一致する必要があります。バンドル URL からサービスとバージョンを抽出するよう、パターンを調整してください。RUM エクスプローラー内のクエリでは、サービス属性を使用してイベントをフィルタリングできます。

制限事項

発生元が割り当てられていないイベント

一部のイベントには関連するハンドリングスタックがないため、発生元に割り当てることができません。

  • 自動的に収集されたアクションイベント
  • XHR および Fetch 以外のリソースイベント
  • 自動的に収集されたビューイベント
  • CORS や CSP の違反

複数マイクロフロントエンド間でのソースマップ解決

スタックトレース内に複数のマイクロフロントエンドのフレームが含まれている場合、イベントは、(エラー送出元の) 最上位フレームから、単一の serviceversion を受け取ります。その単一のサービスではイベントのソースマップが解決されるため、他のマイクロフロントエンドのフレームは、それぞれの service の下でソースマップが正しくアップロードされていた場合でも、縮小化されたままになります。

どのマイクロフロントエンドのソースマップを使用するかを制御するには、手動割り当てアプローチを使用し、beforeSend により event.serviceevent.version を設定します。縮小化解除されるのは、選択されたマイクロフロントエンドに属するフレームだけです。

Datadog でマイクロフロントエンドデータを探索する

セットアップ後、RUM イベントの serviceversion により、どのマイクロフロントエンドが各イベントを生成したかが特定されます。これらの属性は Datadog のさまざまな場所で使用されます。

  • サイドパネル: serviceversion の属性は、RUM エクスプローラーのセッション、ビュー、エラー、リソース、アクション、長時間タスクのサイドパネルに表示されます。
  • RUM サマリーダッシュボード: RUM サマリーダッシュボードで serviceversion を使用することにより、パフォーマンスメトリクスをフィルタリングしてそのスコープを限定し、特定のマイクロフロントエンドに絞り込みます。
  • カスタムダッシュボード: serviceversion を使用することにより、各マイクロフロントエンドを個別にモニターできるダッシュボードを作成します。

各マイクロフロントエンドを表す serviceversion のタグは、以下の無制限 RUM メトリクスにも含まれています。

  • rum.measure.error
  • rum.measure.operation
  • rum.measure.operation.duration

Further reading