RUM とトレース

概要

APM と Real User Monitoring のインテグレーションにより、Web およびモバイルアプリケーションからのリクエストを対応するバックエンドトレースにリンクできます。この組み合わせにより、1 つのレンズを通してフロントエンドとバックエンドの完全なデータを確認できます。

RUM のフロントエンドデータに加えて、トレース ID 挿入のバックエンド、インフラストラクチャー、ログ情報を使用して、スタック内の問題を特定し、ユーザーに起こっていることを理解します。

iOS アプリケーションのトレースだけを Datadog に送信し始めるには、iOS トレース収集をご覧ください。

使用方法

前提条件

  • RUM アプリケーションの対象となるサービスに APM トレーシングを設定していること。
  • サービスが HTTP サーバーを使用していること。
  • HTTP サーバーで、分散型トレーシングをサポートするライブラリが使用されていること。
  • ご利用の SDK に応じて次の設定を行っていること。
    • Browser SDK の場合は、RUM エクスプローラーで XMLHttpRequest (XHR) または Fetch リソースを allowedTracingUrls に追加していること。
    • Mobile SDK の場合は、Native または XMLHttpRequest (XHR) を firstPartyHosts に追加していること。
  • allowedTracingUrls または firstPartyHosts へのリクエストに対応するトレースがあること。

RUM の設定

注: RUM とトレースの構成では、RUM で APM の有料データを使用するため、APM の請求に影響を与える可能性があります。

  1. RUM ブラウザモニタリングを設定します。

  2. RUM SDK を初期化します。ブラウザアプリケーションによって呼び出される内部のファーストパーティオリジンのリストを使用して、allowedTracingUrls 初期化パラメーターを設定します。

    npm インストールの場合:

    import { datadogRum } from '@datadog/browser-rum'
    
    datadogRum.init({
      clientToken: '<CLIENT_TOKEN>',
      applicationId: '<APPLICATION_ID>',
      site: 'datadoghq.com',
      //  service: 'my-web-application',
      //  env: 'production',
      //  version: '1.0.0',
      allowedTracingUrls: [
        "https://api.example.com",
        // Matches any subdomain of my-api-domain.com, such as https://foo.my-api-domain.com
        /^https:\/\/[^\/]+\.my-api-domain\.com/,
        // You can also use a function for advanced matching:
        (url) => url.startsWith("https://api.example.com")
      ],
      sessionSampleRate: 100,
      sessionReplaySampleRate: 100, // if not specified, defaults to 100
      trackResources: true,
      trackLongTasks: true,
      trackUserInteractions: true,
    })
    

    CDN インストールの場合:

    window.DD_RUM.init({
       clientToken: '<CLIENT_TOKEN>',
       applicationId: '<APPLICATION_ID>',
       site: 'datadoghq.com',
       //  service: 'my-web-application',
       //  env: 'production',
       //  version: '1.0.0',
       allowedTracingUrls: [
         "https://api.example.com",
         // Matches any subdomain of my-api-domain.com, such as https://foo.my-api-domain.com
         /^https:\/\/[^\/]+\.my-api-domain\.com/,
         // You can also use a function for advanced matching:
         (url) => url.startsWith("https://api.example.com")
       ],
       sessionSampleRate: 100,
       sessionReplaySampleRate: 100, // if not included, the default is 100
       trackResources: true,
       trackLongTasks: true,
       trackUserInteractions: true,
     })
    

    To connect RUM to Traces, you need to specify your browser application in the service field.

    allowedTracingUrls matches the full URL (<scheme>://<host>[:<port>]/<path>[?<query>][#<fragment>]). It accepts the following types:

    • string: matches any URL that starts with the value, so https://api.example.com matches https://api.example.com/v1/resource.
    • RegExp: matches if any substring of the URL matches the provided RegExp. For example, /^https:\/\/[^\/]+\.my-api-domain\.com/ matches URLs like https://foo.my-api-domain.com/path, but not https://notintended.com/?from=guess.my-api-domain.com. Note: The RegExp is not anchored to the start of the URL unless you use ^. Be careful, as overly broad patterns can unintentionally match unwanted URLs and cause CORS errors.
    • function: evaluates with the URL as parameter. Returning a boolean set to true indicates a match.
RegExp を使用する場合、パターンは URL 全体に対して部分文字列としてテストされ、プレフィックスのみではありません。意図しない一致を避けるために、`^`で RegExp をアンカーし、できるだけ具体的にしてください。
  1. (オプション) traceSampleRate 初期化パラメーターを構成して、バックエンドトレースの一定割合を保持します。設定されていない場合、ブラウザリクエストからのトレースの 100% が Datadog に送信されます。例えば、バックエンドトレースの 20 % を保持するには:

    import { datadogRum } from '@datadog/browser-rum'
    
    datadogRum.init({
        ...otherConfig,
        traceSampleRate: 20
    })
    

: traceSampleRate は RUM セッションのサンプリングに影響を与えません。バックエンドトレースのみがサンプリングされます。

  1. (オプション) traceSampleRate を設定している場合、バックエンドサービス側のサンプリング判定が適用されるように、初期化パラメーター traceContextInjectionsampled に設定してください (デフォルトは sampled です)。

    例えば、Browser SDK で traceSampleRate を 20% に設定した場合:

    • traceContextInjectionall に設定されている場合、バックエンドトレースの 20% が保持され、バックエンドトレースの 80% が破棄されます。
    traceContextInjection は all に設定されています
    • When traceContextInjection is set to sampled, 20% of backend traces are kept. For the remaining 80%, the browser SDK does not inject a sampling decision. The decision is made on the server side and is based on the SDK head-based sampling configuration. In the example below, the backend sample rate is set to 40%, and therefore 32% of the remaining backend traces are kept.

      traceContextInjection は sampled に設定されています
エンドツーエンドトレースは、Browser SDK が初期化された後に送信されたリクエストで利用できます。初期 HTML ドキュメントおよび初期のブラウザリクエストのエンドツーエンドトレースはサポートされていません。
  1. RUM Android モニタリングを設定します。

  2. Android トレース収集を設定します。

  3. モジュールレベルの build.gradle ファイルに dd-sdk-android-okhttp ライブラリへの Gradle 依存関係を追加します。

    dependencies {
        implementation "com.datadoghq:dd-sdk-android-okhttp:x.x.x"
    }
    
  4. Android アプリケーションによって呼び出される内部のファーストパーティオリジンのリストを使用して、OkHttpClient インターセプターを構成します。

    val tracedHosts = listOf("example.com", "example.eu")
    
    val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(DatadogInterceptor.Builder(tracedHosts).build())
        .addNetworkInterceptor(TracingInterceptor.Builder(tracedHosts).build())
        .eventListenerFactory(DatadogEventListener.Factory())
        .build()
    

    By default, all subdomains of listed hosts are traced. For instance, if you add example.com, you also enable the tracing for api.example.com and foo.example.com.

  5. (オプション) traceSampleRate パラメーターを構成して、バックエンドトレースの一定割合を保持します。設定されていない場合、アプリケーションリクエストからのトレースの 100% が Datadog に送信されます。バックエンドトレースの 20% を保持する場合:

    val tracedHosts = listOf("example.com")
    
    val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(
          DatadogInterceptor.Builder(tracedHosts)
              .setTraceSampleRate(20f)
              .build()
        )
        .build()
    

:

  • traceSampleRate は RUM セッションのサンプリングに影響を与えません。バックエンドトレースのみがサンプリングされます。
  • Datadog の設定でカスタムトレースヘッダータイプを定義し、GlobalTracer に登録されたトレーサーを使用している場合は、使用中の SDK に対して同じトレースヘッダータイプが設定されていることを確認してください。
  1. RUM iOS モニタリングを設定します。

  2. RUM および URLSession のインスツルメンテーションを、urlSessionTracking 設定および firstPartyHostsTracing パラメーターで有効にします。

    RUM.enable(
        with: RUM.Configuration(
            applicationID: "<rum application id>",
            urlSessionTracking: .init(
                firstPartyHostsTracing: .trace(
                    hosts: [
                        "example.com",
                        "api.yourdomain.com"
                    ]
                )
            )
        )
    )
    

    デフォルトでは、リストされたホストのすべてのサブドメインがトレースされます。たとえば、example.com を追加すると、api.example.com および foo.example.com のトレースも有効になります。

    トレース ID の注入は、URLSessionURLRequest を提供している場合に機能します。分散トレーシングは、URL オブジェクトを使用している場合には機能しません。

  3. (オプション) DNS 解決、SSL ハンドシェイク、最初のバイトまでの時間、接続時間、ダウンロード時間などの詳細なタイミング内訳を取得するには、SessionDelegate タイプに対して URLSessionInstrumentation を有効にします。

    URLSessionInstrumentation.enableDurationBreakdown(
        with: .init(
            delegateClass: <YourSessionDelegate>.self
        )
    )
    
    let session = URLSession(
        configuration: ...,
        delegate: <YourSessionDelegate>(),
        delegateQueue: ...
    )
    

    : 分散トレーシングは自動的に機能しますが、URLSessionInstrumentation を有効にした後はトレースのタイミングがより正確になります。

  4. (オプション) sampleRate パラメーターを設定して、バックエンドトレースの一定割合を保持します。設定されていない場合、アプリケーションリクエストからのトレースの 100% が Datadog に送信されます。

    バックエンドトレースの 20% を保持する場合:

    RUM.enable(
        with: RUM.Configuration(
            applicationID: "<rum application id>",
            urlSessionTracking: .init(
                firstPartyHostsTracing: .trace(
                    hosts: [
                        "example.com",
                        "api.yourdomain.com"
                    ],
                    sampleRate: 20
                )
            )
        )
    )
    

: sampleRate は RUM セッションのサンプリングに影響を与えません。バックエンドトレースのみがサンプリングされます。

  1. RUM React Native モニタリングを設定します。

  2. firstPartyHosts の初期化パラメーターを設定して、React Native アプリケーションが呼び出す内部のファーストパーティオリジンのリストを定義します。

    const config = new DatadogProviderConfiguration(
        // ...
    );
    config.firstPartyHosts = ["example.com", "api.yourdomain.com"];
    

    By default, all subdomains of listed hosts are traced. For instance, if you add example.com, you also enable tracing for api.example.com and foo.example.com.

  3. (オプション) resourceTracingSamplingRate 初期化パラメーターを設定して、バックエンドトレースの一定割合を保持します。設定されていない場合、アプリケーションリクエストからのトレースの 100% が Datadog に送信されます。

    バックエンドトレースの 20% を保持する場合:

    const config = new DatadogProviderConfiguration(
        // ...
    );
    config.resourceTracingSamplingRate = 20;
    

    Note: resourceTracingSamplingRate does not impact RUM sessions sampling. Only backend traces are sampled out.

  1. RUM Flutter モニタリングを設定します。

  2. リソースを自動追跡の指示に従って、Datadog Tracking HTTP Client パッケージを含め、HTTP トラッキングを有効にします。これには、Flutter アプリケーションが呼び出す内部のファーストパーティオリジンのリストを追加するための初期化への以下の変更が含まれます。

    final configuration = DatadogConfiguration(
      // ...
      // added configuration
      firstPartyHosts: ['example.com', 'api.yourdomain.com'],
    )..enableHttpTracking()
    

RUM for Roku は、 Datadog サイト上では利用できません。

  1. RUM Roku モニタリングを設定します。

  2. ネットワークリクエストを行うには、datadogroku_DdUrlTransfer コンポーネントを使用します。

        ddUrlTransfer = datadogroku_DdUrlTransfer(m.global.datadogRumAgent)
        ddUrlTransfer.SetUrl(url)
        ddUrlTransfer.EnablePeerVerification(false)
        ddUrlTransfer.EnableHostVerification(false)
        result = ddUrlTransfer.GetToString()
    
  1. RUM Kotlin Multiplatform モニタリングを設定します。

  2. Ktor インスツルメンテーションを設定します。

  3. Datadog Ktor Plugin の設定において、tracedHosts 初期化パラメーターを使用し、Kotlin Multiplatform アプリケーションが呼び出す内部 (ファーストパーティ) のドメインリストを定義してください。

    val ktorClient = HttpClient {
        install(
            datadogKtorPlugin(
                tracedHosts = mapOf(
                    "example.com" to setOf(TracingHeaderType.DATADOG),
                    "example.eu" to setOf(TracingHeaderType.DATADOG)
                ),
                traceSampleRate = 100f
            )
        )
    }
    

    By default, all subdomains of listed hosts are traced. For instance, if you add example.com, you also enable tracing for api.example.com and foo.example.com.

  4. (オプション) traceSampleRate 初期化パラメーターを設定して、バックエンドトレースの一定割合を保持します。設定されていない場合、アプリケーションリクエストからのトレースの 20% が Datadog に送信されます。

    バックエンドトレースの 100% を保持する場合:

    val ktorClient = HttpClient {
        install(
            datadogKtorPlugin(
                tracedHosts = mapOf(
                    "example.com" to setOf(TracingHeaderType.DATADOG),
                    "example.eu" to setOf(TracingHeaderType.DATADOG)
                ),
                traceSampleRate = 100f
            )
        )
    }
    

    Note: traceSampleRate does not impact RUM sessions sampling. Only backend traces are sampled out.

セットアップの検証

RUM との APM インテグレーションが構成されていることを検証するには、RUM をインストールした SDK に基づいて以下の手順に従ってください。

  1. アプリケーションのページにアクセスします。
  2. ブラウザの開発者ツールで、Network タブを開きます。
  3. 相関が期待されるリソースリクエストのリクエストヘッダーに Datadog の相関ヘッダーが含まれていることを確認します。
  1. Android Studio からアプリケーションを実行します。
  2. アプリケーションの画面にアクセスします。
  3. Android Studio の Network Inspector を開きます。
  4. RUM リソースのリクエストヘッダーをチェックし、SDK によって必要なヘッダーが設定されていることを検証します。
  1. Xcode からアプリケーションを実行します。
  2. アプリケーションの画面にアクセスします。
  3. Xcode の Network Connections and HTTP Traffic instrument を開きます。
  4. RUM リソースのリクエストヘッダーをチェックし、SDK によって必要なヘッダーが設定されていることを検証します。
  1. Xcode (iOS) または Android Studio (Android) からアプリケーションを実行します。
  2. アプリケーションの画面にアクセスします。
  3. Xcode の Network Connections and HTTP Traffic instrument または Android Studio の Network Inspector を開きます。
  4. RUM リソースのリクエストヘッダーをチェックし、SDK によって必要なヘッダーが設定されていることを検証します。
  1. 希望の IDE または flutter run を使ってアプリケーションを実行します。
  2. アプリケーションの画面にアクセスします。
  3. Flutter の Dev Tools を開き、Network View に移動します。
  4. RUM リソースのリクエストヘッダーをチェックし、SDK によって必要なヘッダーが設定されていることを検証します。
  1. Xcode (iOS) または Android Studio (Android) からアプリケーションを実行します。
  2. アプリケーションの画面にアクセスします。
  3. Xcode の Network Connections and HTTP Traffic instrument または Android Studio の Network Inspector を開きます。
  4. RUM リソースのリクエストヘッダーをチェックし、SDK によって必要なヘッダーが設定されていることを検証します。

RUM Explorer からトレースへ

RUM とトレース

RUM Explorer からトレースを表示するには:

  1. list of sessions に移動し、トレースが利用可能なセッションをクリックします。@_dd.trace_id:* を使用して、トレースを持つリソースをクエリすることもできます。

セッションを選択すると、リクエストの所要時間の内訳、各スパンのフレームグラフ、および View Trace in APM リンクが表示されます。

トレースから RUM Explorer へ

RUM とトレース

トレースから RUM イベントを表示するには:

  1. トレースビュー内で、VIEW をクリックするとビューのライフサイクル中に作成されたすべてのトレースを表示でき、RESOURCE をクリックすると概要タブから特定のリソースに関連するトレースを表示できます。
  2. See View in RUM または See Resource in RUM をクリックして、RUM Explorer で対応するイベントを開きます。

サポートされているライブラリ

サポートされているバックエンドライブラリは、ネットワークリクエストを受け取るサービス上に導入する必要があります。

OpenTelemetry のサポート

RUM は、OpenTelemetry ライブラリを使ってインスツルメントされたバックエンドとリソースを接続するため、複数のプロパゲータータイプをサポートしています。

デフォルトのインジェクションスタイルは tracecontextDatadog です。

: Next.js/Vercel など、OpenTelemetry を使用するバックエンドフレームワークを使用している場合は、以下の手順に従ってください。

  1. 上記に従い、RUM を APM に接続するためのセットアップを行います。

  2. allowedTracingUrls を次のように変更します。

    import { datadogRum } from '@datadog/browser-rum'
    
    datadogRum.init({
        ...otherConfig,
        allowedTracingUrls: [
          { match: "https://api.example.com", propagatorTypes: ["tracecontext"]}
        ]
    })
    

    match accepts the same parameter types (string, RegExp or function) as when used in its simple form, described above.

    propagatorTypes accepts a list of strings for desired propagators:

  1. 上記に従い、RUM を APM に接続するためのセットアップを行います。

  2. .traceWithHeaders(hostsWithHeaders:sampleRate:).trace(hosts:sampleRate:) の代わりに次のように使用します。

      RUM.enable(
          with: RUM.Configuration(
              applicationID: "<rum application id>",
              urlSessionTracking: .init(
                  firstPartyHostsTracing: .traceWithHeaders(
                      hostsWithHeaders: [
                          "api.example.com": [.tracecontext]
                      ],
                      sampleRate: 100
                  )
              )
          )
      )
    

    .traceWithHeaders(hostsWithHeaders:sampleRate:) takes Dictionary<String, Set<TracingHeaderType>> as a parameter, where the key is a host and the value is a list of supported tracing header types.

    TracingHeaderType in an enum representing the following tracing header types:

  1. 上記に従い、RUM を APM に接続するためのセットアップを行います。

  2. 内部のファーストパーティオリジンのリストと、使用するトレーシングヘッダータイプを指定して、次のように OkHttpClient インターセプターを構成します。

    val tracedHosts = mapOf("example.com" to setOf(TracingHeaderType.TRACECONTEXT),
                          "example.eu" to setOf(TracingHeaderType.DATADOG))
    
    val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(DatadogInterceptor.Builder(tracedHosts).build())
        .addNetworkInterceptor(TracingInterceptor.Builder(tracedHosts).build())
        .eventListenerFactory(DatadogEventListener.Factory())
        .build()
    

    TracingHeaderType is an enum representing the following tracing header types:

  1. RUM を APM と接続するように設定します。

  2. 内部のファーストパーティオリジンのリストと、使用するトレーシングヘッダータイプを指定して、次のように RUM SDK を構成します。

    const config = new DatadogProviderConfiguration(
        // ...
    );
    config.firstPartyHosts = [{
        match: "example.com",
        propagatorTypes: [
            PropagatorType.TRACECONTEXT,
            PropagatorType.DATADOG
        ]
    }];
    

    PropagatorType is an enum representing the following tracing header types:

  1. 上記に従い、RUM を APM に接続するためのセットアップを行います。

  2. firstPartyHostsWithTracingHeadersfirstPartyHosts の代わりに次のように使用します。

    final configuration = DatadogConfiguration(
      // ...
      // added configuration
      firstPartyHostsWithTracingHeaders: {
        'example.com': { TracingHeaderType.tracecontext },
      },
    )..enableHttpTracking()
    

    firstPartyHostsWithTracingHeaders takes Map<String, Set<TracingHeaderType>> as a parameter, where the key is a host and the value is a list of supported tracing header types.

    TracingHeaderType in an enum representing the following tracing header types:

  1. RUM を APM と接続するように設定します。

  2. 内部のファーストパーティオリジンのリストと、使用するトレーシングヘッダータイプを指定して、次のように RUM SDK を構成します。

    val ktorClient = HttpClient {
        install(
            datadogKtorPlugin(
                tracedHosts = mapOf(
                    "example.com" to setOf(TracingHeaderType.DATADOG),
                    "example.eu" to setOf(TracingHeaderType.DATADOG)
                ),
                traceSampleRate = 100f
            )
        )
    }
    

    TracingHeaderType is an enum representing the following tracing header types:

RUM リソースがトレースにリンクされる仕組み

Datadog は、分散型トレーシングプロトコルを使用し、以下の HTTP ヘッダーを設定します。デフォルトでは、トレースコンテキストと Datadog 固有のヘッダーの両方が使用されます。

x-datadog-trace-id
Real User Monitoring SDK から生成されました。Datadog がトレースを RUM リソースにリンクできるようにします。
x-datadog-parent-id
Real User Monitoring SDK から生成されました。Datadog がトレースの最初のスパンを生成できるようにします。
x-datadog-origin: rum
Real User Monitoring SDK から生成されました。Datadog がトレースの発生元を検出できるようにします。
x-datadog-sampling-priority
トレースがサンプリングされた場合は 1、サンプリングされていない場合は 0 に設定されます。
traceparent: [version]-[trace id]-[parent id]-[trace flags]
version: 現在の仕様では、バージョンは 00 に設定されていると想定されています。
trace id: 128 ビットのトレース ID (32 文字の 16 進数)。ソーストレース ID は 64 ビットで、APM との互換性を保つためです。
parent id: 64 ビットのスパン ID (16 文字の 16 進数)。
trace flags: サンプリングされた (01) またはサンプリングされていない (00)

トレース ID 変換: 128 ビットの W3C トレース ID は、元の 64 ビットのソーストレース ID に先頭のゼロを追加して作成されます。これにより、APM との互換性が確保され、W3C Trace Context 仕様に準拠します。元の 64 ビットのトレース ID は、128 ビットの W3C Trace Context トレース ID の下位 64 ビットになります。

tracestate: dd=s:[sampling priority];o:[origin]
dd: Datadogのベンダープレフィックス。
sampling priority: トレースがサンプリングされた場合は 1、サンプリングされていない場合は 0 に設定されます。
origin: 生成されたトレースが Real User Monitoring から APM インデックススパン数に影響を与えないように、常に rum に設定します。

:

ソーストレース ID (64ビット): 8448eb211c80319c

W3C Trace Context (128 ビット): 00000000000000008448eb211c80319c

関係は、元の 64 ビットのトレース ID 8448eb211c80319c に 16 個の先頭ゼロ (0000000000000000) を付加して 128 ビットの W3C トレース ID が作成されることを示しています。

traceparent の完全な例:
traceparent: 00-00000000000000008448eb211c80319c-b7ad6b7169203331-01
tracestate: dd=s:1;o:rum
b3: [trace id]-[span id]-[sampled]
trace id: 64 ビットのスパン ID (16 文字の 16 進数)。
span id: 64 ビットのスパン ID (16 文字の 16 進数)。
sampled: True (1) または False (0)
b3 単一ヘッダーの例:
b3: 8448eb211c80319c-b7ad6b7169203331-1
b3 複数ヘッダーの例:
X-B3-TraceId: 8448eb211c80319c
X-B3-SpanId: b7ad6b7169203331
X-B3-Sampled: 1

これらの HTTP ヘッダーは CORS セーフリストに含まれていないため、SDK が監視対象として設定されているリクエストを処理するサーバーで Access-Control-Allow-Headers を構成する必要があります。サーバーはまた、クロスサイト URL でトレースが許可されている場合、ブラウザが各リクエストの前に行う preflight requests (OPTIONS リクエスト) を受け入れる必要があります。

トレースの保持

取り込まれたトレースは、Live Search エクスプローラーで 15 分間利用可能です。トレースをより長い期間保持するには、APM 保持フィルターを作成してください。これらの保持フィルターを任意のスパンタグにスコープして、重要なページやユーザーアクションのトレースを保持します。

RUM Without Limits を使用する場合、特定の RUM セッションに関連する APM トレースを保持するためにクロスプロダクト保持フィルターを使用することもでき、フロントエンドとバックエンドの相関を最適化します。デフォルトでは、RUM のセッションとそのトレースは自動的に保持されるの 1 % が自動的に保持され、追加費用はかかりません。

APM クォータへの影響

RUM とトレースを接続することで、APM に取り込まれるボリュームが大幅に増加する可能性があります。初期化パラメーター traceSampleRate を使用して、ブラウザおよびモバイルリクエストから取り込むバックエンドトレースの割合を制御します。

cross-product retention filters を設定することで、APM にインデックスされるボリュームが増加する可能性もあります。cross-product retention filters の保持率を使用して、インデックスするバックエンドトレースの割合を制御します。

参考資料