この投稿は続編です。
New Relic CodeStreamを試してみるというブログを先日あげました。
紆余曲折あったものの、なんとか連携できて無事にNew Relic上でエラーを検知したらNew Relicの画面から問題のソースコードおよびその箇所をIDEで開くということができるようになりました。
ただ、前回のブログでは以下のような疑問が残りました。
プロダクションで実行されてるバージョンと手元で開発中のバージョンが違うってのは普通によくあることだと思うのでそのあたりをどう扱えばいいのか。
正直これができないと実際に使うのは難しいなと思ってたのですが、その後の調べでちゃんと紐付けることができそうなことがわかったので今回はそれを試していきます。
前提
まず、今回の環境は前回のブログで書いたように以下の環境で試しています。
- IDEはVS Code
- Remote Containersを利用して開発
- サンプルアプリはNext.jsとTypeScriptで作成
- サンプルアプリはServer Side Rendering(SSR)するように実装
- SSRを実行するサーバ側(といってもRemote Containersで使ってるコンテナ)にAPMのエージェントを導入してモニタリング
その他の詳細は前回のブログを見てください。利用したサンプルのコードはこちらにあります。
リリースバージョンと紐付ける
ここで「リリースバージョンと紐付ける」と言っているのは実際にリリースしているアプリケーションのバージョン、つまりモニタリング対象になっているバージョンとCodeStreamで表示するソースコードのバージョンを紐付けるということです。
これによって、ソースコードリポジトリ上は開発が進んでていて実際にリリースされているバージョンより先に進んでいる場合などに、CodeStreamでエラー箇所を開いたときにポイントされる箇所がずれるという問題がなくなります。
このあたり実はドキュメントに書かれていました。
簡単に言うと、APMエージェントを実行している環境(つまりNode.jsのサーバが動いている環境)で以下の環境変数を設定することで望んでいることは実現できそうです。
- NEW_RELIC_METADATA_REPOSITORY_URL
- NEW_RELIC_METADATA_COMMIT
- NEW_RELIC_METADATA_RELEASE_TAG
Gitのコミットハッシュ(commit SHA)もしくはリリースタグをAPMエージェントに教えてあげることでCodeStreamが開くときのバージョンを特定されるようです。
というわけでやっていきます。
環境変数をセットする
これはNode.jsが動くサーバ上で設定します。まず NEW_RELIC_METADATA_REPOSITORY_URL
ですがこれはGitHub上のURLを指定します。.git
まで含めたほうがよいみたい。
次にNEW_RELIC_METADATA_COMMIT
ですがこれはサーバ上で実際に動いているコードのコミットハッシュを指定する必要があります。
そして最後にNEW_RELIC_METADATA_RELEASE_TAG
ですがこれはGit上のリリースタグを指定する。一つ前のNEW_RELIC_METADATA_COMMIT
とどちらか(もしくは両方)を指定すればいいみたい。実際にはリリースタグ設定してリリースすることのほうが多そうなので、今回はこちらのNEW_RELIC_METADATA_RELEASE_TAG
のみ設定してやってみます。
まずは現在のソースコードにタグを作成してプッシュしておきます。
$ git tag v1.0 $ git tag v1.0 $ git push origin main Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (7/7), done. Writing objects: 100% (7/7), 633 bytes | 79.00 KiB/s, done. Total 7 (delta 5), reused 0 (delta 0) remote: Resolving deltas: 100% (5/5), completed with 4 local objects. To https://github.com/Keisuke69/codestream-with-remotecontainer 21a8ea9..b444937 main -> main
続いて環境変数をセットしていきます。今回はサンプルアプリのリポジトリURLをセットしてます。リリースタグとしては先に設定したv1.0
という値をセットします。
$ export NEW_RELIC_METADATA_REPOSITORY_URL="https://github.com/Keisuke69/codestream-with-remotecontainer.git" $ export NEW_RELIC_METADATA_RELEASE_TAG="v1.0"
これらをセットしたらyarn build
でビルドしたのちサーバを起動します。Next.jsのアプリを起動する場合はこんな感じで起動します。
$ node -r newrelic node_modules/.bin/next start
結果確認
さて、起動したら実際にリクエストしてエラー箇所をIDEで表示してみるわけですが、今回はテストでエラーを発生させてNew Relicで検知できるようにNew Relicが提供するAPMエージェントのAPIであるnoticeError()
を使ってます。HTTPステータスの500が返るようなものはハンドリングされているということでそのままではNew Relicがトレースまで表示してくれなかったりするからです。
が、なんか左側にSHAが紐付けられていないってメッセージが出てますね。リリースタグだけセットしたのがダメだったのかな?ということでコミットハッシュも設定してみます。
$ export NEW_RELIC_METADATA_COMMIT="b44493747057aa8720bf59628670508f13eb75e0"
で、またサーバを再起動してリクエストしてみます。でもやっぱり消えません。
ふと気づきました。前回のブログでも最後のほうに書いていたのですが、
実際にはビルド後の.next/server/pages/index.jsみたいなファイルに紐づきます。
このファイルはビルドすると更新されてしまうし、当然ながらリポジトリにコミットもしないです。
つまりですね、Next.jsのアプリの場合にビルド後のファイルが.next
に出力されるのですが、これはコミット対象にしていないことが多いので当然ながらコミットハッシュなども存在しないのですね。
なので、リリースバージョンのコードを表示するっていうのができないんだと思います。
結論
やはりNext.jsのアプリだと期待した通りにはまだいかないよう。ビルド結果のファイルはリポジトリに含めないことが多いと思うのでこのあたりをどう解決すべきなのか。簡単に解決するには.next
フォルダもまるっとコミットしてしまうことなんだろうけど。でもこれってJavaの場合とかも同じだと思うんだけど、そういったコンパイルが必要な言語とかだとどうなるんだろうか。
ちなみに、CodeStreamをうまく使うにあたっては今回のように環境変数をセットする必要があるわけですが、コミットハッシュやリリースタグを設定する必要があるということはアプリケーションのリリースフローの中でこれらを更新してあげるように工夫する必要があります。