NewRelic ブラウザモニタリングのソースマップで色々ハマった話
こんにちは。エンジニアの中畑(@yn2011)です。千葉県は最高です。
今回はNewRelic ブラウザモニタリングを使用して JavaScript のエラー収集を行おうとした際に、NewRelic のソースマップアップロード機能の仕様で色々とハマってしまったというお話をします。
ソースマップアップロード API について
NewRelic ブラウザモニタリングでは、ソースマップというファイルを利用して発生した JavaScript エラーのスタックトレースを取得することができます。
ソースマップは、以下のような内容のファイルです。
{
"version": 3,
"file": "static/chunks/254-be419541614271942b8c.js",
"mappings": "gFAAoEA,...
}
NewRelic ブラウザモニタリングにはソースマップのバージョン管理機能があり、ソースマップにユニークな識別子をアップロード時に付与することができます。提供されているソースマップのアップロード API を利用してアップロード時に識別子の付与ができます。
publishSourcemap({
sourcemapPath: './dist/bundle.js.map',
javascriptUrl: 'https://example.com/assets/bundle.js',
...
releaseName: 'OPTIONAL RELEASE NAME', // 追加
releaseId: 'OPTIONAL RELEASE ID', // 追加
}, function (err) { console.log(err || 'Source map upload done')})
releaseName
と releaseId
を指定できることに違和感を持った方もいるかもしれません。これは次項の伏線です。
ハマリポイント
releaseId と releaseName は両方必須
早速伏線を回収します。NewRelic ブラウザモニタリングでバージョン管理を行う場合は、releaseName
と releaseId
の両方が必須になります。
ドキュメントに記載はないように認識していますが、 @newrelic/publish-sourcemap の実装を確認すると、しっかり条件式に含まれていました。
if (releaseName && releaseId) {
console.log('Using release name:', releaseName, 'and release id:', releaseId)
request = request.field('releaseName', releaseName)
request = request.field('releaseId', releaseId)
}
コミットハッシュを活用する場合など、どちらか 1 つの項目を利用できれば十分なことが多いと思います。なぜこのような仕様になっているのかは分かりませんでした。
コンフリクトエラー
ソースマップのバージョン管理を行わない場合は、releaseName
と releaseId
を指定する必要はありません。しかし、1 度これらの項目を空でアップロードしてしまうと、次にアップロードする際に releaseId
と releaseName
を指定してアップロードしてもコンフリクトエラーというレスポンスが返り、アップロードが失敗します。
コンフリクトエラーは、NewRelic に同一のソースマップをアップロードした場合に発生する仕様となっています。releaseName
と releaseId
が異なる場合は別のソースマップとして解釈されるためアップロードが可能です。
バージョン管理を行う場合は、1度、releaseName
と releaseId
が空のソースマップを削除し、再度アップロードする必要があります。
ブラウザ側で addRelease を呼び出す必要がある
ソースマップのバージョン管理を行う場合、ブラウザ側で browser agent API から次のメソッドを呼び出す必要があります。
newrelic.addRelease(string $release_name, string $release_id)
このメソッドを呼び出さないと、発生した JavaScript エラーを正しいバージョンのソースマップにマッピングすることができません。メソッドを呼び出さずに JavaScript エラーを発生させた場合、NewRelic の画面上では releaseName
と releaseId
は空になります。
addRelease
の呼び出しの実装としては、スニペットの末尾への追加が可能です。
NewRelic ブラウザモニタリングを利用する場合は、New Relic から提供されるスニペットをブラウザで実行する必要があります。このスニペットの実行後に、browser agent API が利用可能になるため、以下のように末尾に呼び出しを追加します。
// 省略...
applicationID:"${config.applicationID}",sa:1};
newrelic.addRelease("foo", "bar"); // 追加
addRelease
の呼び出しは、類似サービスである Sentry では不要であったため、検証時に気づかずハマってしまいました。
まとめ
NewRelic ブラウザモニタリングのソースマップに関するハマりポイントを 3 つ書きました。
最終的に、プロダクトではソースマップバージョン管理機能の導入は見送りましたが、今後必要に応じて対応を検討する予定です。
最後までお読み頂きありがとうございました。
