NewRelic × OpenReplay

はじめに

弊社ではフロントエンドのツールにOSS製のSessionReplay、OpenReplayを導入しています。 OpenReplay側にNewRelicとインテグレーションを組むドキュメントがありますが、内容も古く非推奨の機能を利用していたため、NewRelicのAPMにあるAPIを利用して擬似的にOpenReplayの録画情報と、Session情報を紐付けることにしました。

実行環境

  • php7.x系
  • newrelic-php5=10.2.0.314

使用例

利用するAPInewrelic_get_trace_metadata()を利用します。 ※ローカル環境ではNewRelicのデーモンを動かしていないので、無くても動作するようにラッパーを用意しています。

<?php
final class TransactionAttribute {

    public static function getMetaData() : array
    {
        if ( extension_loaded('newrelic') ) {
            return newrelic_get_trace_metadata();
        }
        return [];
    }

}

viewに渡すスクリプトで、metadataを渡してOpenReplayへ送るようにします。

<script>
    var initOpts = {
        projectKey: $this->projectKey,
        ingestPoint: $this->openReplayEndpoint,
        defaultInputMode: 1, 
        obscureTextNumbers: false,
        obscureTextEmails: true,
    };
    // ココ!!
    var startOpts = {userID: '', metadata: TransactionAttribute::getMetaData() };
    (function (A, s, a, y, e, r) {
        r = window.OpenReplay = [e, r, y, [s - 1, e]];
        s = document.createElement('script');
        s.src = A;
        s.async = !a;
        document.getElementsByTagName('head')[0].appendChild(s);
        r.start = function (v) {
            r.push([0])
        };
        r.stop = function (v) {
            r.push([1])
        };
        r.setUserID = function (id) {
            r.push([2, id])
        };
        r.setUserAnonymousID = function (id) {
            r.push([3, id])
        };
        r.setMetadata = function (k, v) {
            r.push([4, k, v])
        };
        r.event = function (k, p, i) {
            r.push([5, k, p, i])
        };
        r.issue = function (k, p) {
            r.push([6, k, p])
        };
        r.isActive = function () {
            return false
        };
        r.getSessionToken = function () {
        };
    })("//static.openreplay.com/3.5.10/openreplay.js", 1, 0, initOpts, startOpts);
</script>

OpenReplayと照合する

バックエンドでエラーが発生すると、以下のようなjsonがNewRelicのLogsに送られてきます。 ※記載するのに、一部情報を削っています

{
  "channel": "app",
  "datetime.timezone": "Asia/Tokyo",
  "datetime.timezone_type": 3,
  "level": 200,
  "method": "GET",
  "plugin.type": "fluentd",
  "session_id": "1a569f2f",
  "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36"
}

この、jsonsession_idをOpenReplayの画面上で検索すると、録画情報と照合することができます。

最後に

通常、NewRelicに情報を集約したい。といったことでログを流したりすることが多いと思いますが、今回はちょっと別の切り口で記事を書いてみました。 NewRelicにある情報と別の情報と合わせてみることによって、トレーサビリティの向上を実現できた例として残しておきたいと思います。