独自監視用の SPA API の利用

New Relic のシングルページアプリ (SPA) API を使うと、New Relic が自動的に監視しないアプリのインタラクションも計測できるようになります。

デフォルトの SPA 監視

New Relic SAP 監視の肝は、BrowserInteraction イベントです。New Relic は、最初のページ読み込み、クリック、フォームのサブミット、履歴の変更時に BrowserInteraction を開始します。デフォルトでは、URL やハッシュ変更につながるイベントのみ保存されます。ブラウザのインタラクションにイベントに関する詳しい情報は、ブラウザのインタラクションをご覧ください。BrowserInteraction イベントの全属性のリストに関しては、BrowserInteraction のデフォルt属性をご覧ください。

ブラウザのインタラクションに関連する全ての AJAX リクエストは、AjaxRequest イベントとして保存されます。AjaxRequest イベントの全属性のリストは、Default AjaxRequest のデフォルト属性をご覧ください。

SPA API

New Relic の SPA API を使うと、特定のブラウザインタラクションに対して独自の監視を追加できます。ルート変更を起こさないようなインタラクション(例えば、動的に更新されるウィジェット)がある場合、そのような New Relic が自動で監視しないインタラクションを監視したい場合に役立ちます。

カスタム・インタラクションは、デフォルト監視と同じように、(AJAX リクエストを含む) 同期、非同期、両方のアクティビティを監視します。

この API では、監視の必要がないと考えるデフォルトで監視対象のインタラクションを無効にすることもできます。

newrelic.interaction()

エージェントバージョン: 963 以上

newrelic.interaction() は、現在のインタラクションにバインドされている新規の API オブジェクトを返します。New Relic がインタラクションを監視していない時にこれが呼ばれた場合は、新規のインタラクションが生成されます。同じインタラクション内で再度呼ばれた場合は、現在のインタラクションを参照する新規のオブジェクトが生成されます。

SPA API メソッドは、 newrelic.interaction() で使用できます。このメソッドは、以下のように変数に割り当てて使うこともできます。

myInteraction = newrelic.interaction()

myInteraction.save()

名前付けられたハンドルは、保存され、インタラクション外から使用されることもありますが、インタラクションが終了した後にメソッドを呼び出しても何も起きません。

戻り値
このメソッドは、特定の BrowserInteraction にバインドされている API オブジェクトを返します。このメソッドが同じ BrowserInteraction に対して呼び出される度に、新しいオブジェクトが生成されます。そして、それは同じインタラクションを参照します。

newrelic.interaction().setName(string NAME, string TRIGGER)

エージェントバージョン: 963 以上

BrowserInteraction の名前とトリガーをセットするのに使います。名前は、. The name will be exposed as the browserInteractionName attribute in the BrowserInteractionbrowserInteractionName として表示され、UI 上でグループ化の値として使用されます。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。/p>
引数
引数 データ型 説明
NAME String null 以外なら、BrowserInteraction イベントの browserInteractionName 属性を設定します。名前が設定されていない場合は、名前には、targetGroupedUrl 属性を使います。
TRIGGER String null 以外なら、BrowserInteraction イベントの trigger 属性を設定します。

インタラクションにカスタム名を追加する例です。

document.getElementById('subscribe').addEventListener('submit', () => {
    newrelic.interaction().setName('createSubscription')
    createSubscription()
})

newrelic.interaction().save()

エージェントバージョン: 963 以上

インタラクションが終了した時に、インタラクションが保存されることを保証します。インタラクションが最初のページ読み込みであったり、それが URL やハッシュ変更をもたらす場合、通常のインタラクションのみが保存され、New Relic に送信されます。この動作を置き換えて、インタラクションの保存を保証したい場合は、このメソッドを呼び出す必要があります。

戻り値
newrelic.interaction(), which is associated with a BrowserInteraction イベントに関連する newrelic.interaction() が生成した同じ API オブジェクトを返します。
カスタムインタラクションの保存の例:

window.addEventListener('scroll', () => {
    if (atBottomOfPage()) {
        newrelic.interaction() // インタラクションの監視の開始
            .setName('loadNextPage') // インタラクション名のセット
            .save(); // 終了時に、BrowserInteraction イベントとしてこのインタラクションが保存されること保証
        loadNextPage() // 次のページ読みこみの開始
    }
})

newrelic.interaction().ignore()

エージェントバージョン: 963 以上

インタラクションを無視するようにします。つまり、保存されないし、New Relic へも送信されないようにします。このメソッドは、save 前後の呼び出しを上書きします。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。
インタラクションを無視する例:

router.addRoute('/uninteresting-route', () => {
    newrelic.interaction() // 現在のインタラクションのハンドルを取得
        .ignore() // 保存されないように、インタラクションを無視
    renderUninterestingRoute() // ルートに描画
})

newrelic.interaction().end()

エージェントバージョン: 963 以上

現時点でインタラクションを終了します。後続のコールバックやリクエストは、このインタラクションには含まれません。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。
早めにのインタラクションを終了する例:

router.addRoute('/profile', () => {
    startSlowBackgroundAjax() // Start work that will continue past the end of the interaction
    renderProfileComponents().then(() => { // Do work that is part of the interaction
        newrelic.interaction().end() // End the interaction once the important components an the page have finished rendering
    })
})

newrelic.interaction().setAttribute(string KEY, any VALUE)

エージェントバージョン: 963 以上

インタラクションに属性を追加します。このインタラクションが保存されていれば、属性は、 BrowserInteraction イベントの新規のプロパティとして確認できます。 newrelic.setCustomAttribute(...) で追加された属性と異なり、インタラクションに追加される属性は、現在のインタラクションのみ適用され、PageAction イベントには追加されません。.

このメソッドでセットされたカスタム属性は、newrelic.setCustomAttribute(...) の呼び出し時にセットされているカスタム属性とサーバーサイドのエージェントがセットしたカスタム属性とマージされます。SPA API でセットされた BrowserInteraction 属性は、最も高い優先順位があり、他の2つの方法で設定された属性を上書きします。attributes set with the SPA API will have the highest precedence, and overwrite attributes set in the other two ways. Attributes set by newrelic.setCustomAttribute(...) にって設定された属性は、その次に優先され、サーバーサイドのカスタム属性を上書きします。サーバーサイドのカスタム属性は、最も低い優先順位tなります。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。
引数
引数 データタイプ 説明
KEY String BrowserInteraction イベントの属性名として利用されます。
VALUE 任意 BrowserInteraction イベントの属性の値として利用されます。これは、文字列、数値、真偽値、オブジェクトを取れます。オブジェクトの場合は、JSON 文字列にシリアライズされます。
カスタム属性の設定の例:

router.addRoute('/profile', () => {
    const user = getCurrentUser()
    newrelic.interaction()
        .setAttribute('username', user.username)
        .setAttribute('userId', user.id)
    renderProfile(user)
})

newrelic.interaction().getContext(function CALLBACK)

エージェントバージョン: 963 以上

現在のインタラクションに関連したコンテキストオブジェクトを引数にもつ非同期に呼び出されるコールバックを取得します。このオブジェクトは、現在のインタラクションに関連した値を保存するのに利用できます。また、インタラクションをまたいで共有され、インタラクションの過程でデータを集約することができる複数の場所から利用できます。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。
引数
引数 データタイプ 説明
CALLBACK Function 引数としてコンテキストオブジェクトのみを取る関数。
データを渡すインタラクションのコンテキストを使用する例:

router.addRoute('/products/{productId}', params => {
    newrelic.interaction().getContext(ctx => ctx.productId = params.productId)
    renderProduct(params.productId)
    updateHash()
})

window.addEventListener('hashchange', (ev) => {
    const interaction = newrelic.interaction()
    interaction.getContext(ctx => {
        if (ctx.productId) {
            interaction.setAttribute('productId', ctx.productId)
        }
    })
})

newrelic.interaction().onEnd(function CALLBACK)

エージェントバージョン: 963 以上

これは、getContext メソッドと似た動きをします。インタラクションが終わった際に一度だけ呼ばれるコールバックを取得します。getContext と同じオブジェクトを引数に渡されます。これは、関数の最後でイベントを変更することができます。例えば、イベントにカスタム属性を追加することができます。

(setName, saveignoresetAttribute)などのインタラクションを修正するために、このメソッドを利用できます。一方、非同期に副作用がある (getContext, onEnd, createTracer) のメソッドでは効果がありません。

戻り値
newrelic.interaction() が生成した同じ API オブジェクトを返します。
引数
引数 データタイプ 説明
CALLBACK Function インタラクションのコンテキストオブジェクトのみを引数として取る関数。
インタラクションの終了時に属性をセットする例:

// router.js
router.addRoute('/dashboard', () => {
    const interaction = newrelic.interaction().onEnd(ctx => {
        interaction.setAttribute(
            'averageChartLoadTime',
            ctx.totalChartLoadTime / ctx.chartLoadCount
        )
    })
    getCharts().forEach(loadChart)
})

// chart-loader.js
function loadChart (chart) {
    const start = Date.now()
    chart.load().then(() => {
        const loadTime = Date.now() - start
        interaction.getContext(ctx => {
             ctx.totalChartLoadTime = (ctx.totalChartLoadTime || 0) + loadTime
             ctx.chartLoadCount += (ctx.chartLoadCount || 0) + 1
        })
    }
}

newrelic.interaction().createTracer(string NAME, function CALLBACK)

エージェントバージョン: 963 以上

このメソッドは、インタラクションのサブコンポーネントごとに時間を計測する方法を提供します。各サブコンポーネントは、それぞれ起動されると、コールバックが実行されるまでの待ち時間とコールバックの JS の実行時間の両方を測定します。また、計測されていない非同期メソッドが生成している非同期のギャップを埋めるという用途にも利用できます。

現在のインタラクションが保存される場合、BrowserTiming Insights イベントは生成され、タイミング情報が SPA Views の breakdown タブに表示されます。

このメソッドは、あなたのコードから呼び出されることを期待したラップされたコールバックメソッドを返します。返されたコールバックが、呼び出されたときに以下の3つのことを行います。

  1. カスタムトレーサの非同期部分の終了を記録
  2. 同じ引数や同じコンテキストで、createTracer に渡された元のコールバックを実行
  3. 元のコールバックの実行時間を計測

that runs createTracer を実行する BrowserInteraction は、BrowserTiming イベントを生成します。コー​​ルバックの中に作成されたどの XHR やカスタムトレースも、インタラクションの一部として含まれます。そのトレーサーの全てが完了するまで、インタラクションが完了したとは見なされません。このようにして、デフォルトではエージェントが処理しない非同期関数を、トレーサーがラップできるようにしています。名前が指定されていない場合は、ノードはインタラクションツリーに追加されず、コールバック時間は、親ノードに帰属します。

戻り値
このメソッドは、非同期時間を終了し、 createTracer に渡されたコールバックを呼び出します(そして時間を計測します)。
引数
引数 データタイプ 説明
NAME String トレーサー名
CALLBACK Function 非同期作業の終了時に実行される同期作業を含むコールバック。このコールバックは、newrelic.interaction().createTracer から返されるラッパー関数を呼び出すことで実行できます。
例: 同期のコードのトレース
特定の JavaScript 関数の呼び出しにかかる時間だけを測定したい場合は、コールバックに code>createTracer に関数を渡すと、返されたラッパーのコールバックをすぐに呼び出すことができます。

newrelic
  .interaction()
  .createTracer('customSegment', function myCallback () {
    // ... do your work ...
  })()

このケースでは、結果のカスタムトレーサーは無視できるくらいの非同期の待ち時間と myCallback の実行時間と等しい同期の持ち時間を持つことになります。

例: 計測されていない非同期 API のトレース
New Relic エージェントは、デフォルトでは (setTimeout 等の)多くの一般的な非同期関数をラップしています。しかし、(例えば、requestAnimationFrame) のようなデフォルトでは対象外となっている関数もあります。(例:websockets 仕様に則った独自の RPC 実装)など、因果関係を簡単に決定できないケースもあります。このようなケースでは、createTracer を利用することで、計測されない関数へのコールバックをインタラクションの一部とみなすようにできます。

コールバックを受け取り、将来のある時点で実行される非同期の関数、doAsyncWork があるとします。コールバックが実行を開始した時との間の時間(非同期の待ち時間)とコールバックの実行時間(同期のコールバック時間)の両方を測定したいとします。

New Relic Browser エージェントがネイティブでラップしいてる非同期の API (setTimeoutsetImmediatePromisefetchXMLHttpRequest) に基づいた非同期のスケジューリングシステムでは、createTracer の利用が必要ないことに注意していください。これらの API によって生成された非同期の境界は、自動的に New Relic Browser エージェントによってブリッジされます。

上記で説明していることを createTracer で実現する方法は以下の通りです。

var wrappedCallback = newrelic
  .interaction()
  .createTracer('customSegment', doTheWork)

doAsyncWork(wrappedCallback)

function doTheWork() {
  // ... do your work ...
}

以下の図は、イベントのタイムラインを示しています。

SPA async timeline image

トレーサータイミングの概要

関連情報

関連する情報は以下のとおりです。