Next.js (App Router) に New Relic の Agent を導入する
この記事は?
Next.js に New Relic APM と New Relic Browser を導入する方法を紹介します。
環境情報
今回は Next.js のチュートリアルをベースとして導入しています。
それ以外は以下の環境で実行をしています
- Apple M1 Max 14.4.1 (23E224)
- Node.js v20.11.1
- Next.js 14.0.2
- React 18.2.0
必要なライブラリの導入
今回の導入において必要なライブラリは以下になります
それぞれを導入します。
npm i newrelic
npm i @types/newrelic
npm i @newrelic/next
各種設定
newrelic.js をコピーしてルートフォルダ配下に配置します。
node_modules/newrelic 配下にあります。
cp node_modules/newrelic.js ./
newrelic.js を編集します
app_name: ['nextjs-dashboard'],
/**
* Your New Relic license key.
*/
license_key: process.env.NEW_RELIC_LICENSE_KEY,
logging: {
/**
* Level at which to log. 'trace' is most useful to New Relic when diagnosing
* issues with the agent, 'info' and higher will impose the least overhead on
* production applications.
*/
level: 'info'
},
/**
* When true, all request headers except for those listed in attributes.exclude
* will be captured for all traces, unless otherwise specified in a destination's
* attributes include/exclude lists.
*/
allow_all_headers: true,
attributes: {
/**
* Prefix of attributes to exclude from all destinations. Allows * as wildcard
* at end.
*
* NOTE: If excluding headers, they must be in camelCase form to be filtered.
*
* @name NEW_RELIC_ATTRIBUTES_EXCLUDE
*/
exclude: [
'request.headers.cookie',
'request.headers.authorization',
'request.headers.proxyAuthorization',
'request.headers.setCookie*',
'request.headers.x*',
'response.headers.cookie',
'response.headers.authorization',
'response.headers.proxyAuthorization',
'response.headers.setCookie*',
'response.headers.x*'
]
}
}
環境変数として New Relic の[ライセンスキ-](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/を取得します。
NEW_RELIC_LICENSE_KEY=<your lisence key>
package.jsonの編集
起動スクリプトに -r @newrelic/next
を読み込ませます。
今回はローカル実行で next dev を実行させているのでそこのみを編集しています。
...
"scripts": {
"build": "next build",
"dev": "NODE_OPTIONS='-r dotenv/config -r @newrelic/next' next dev",
"prettier": "prettier --write --ignore-unknown .",
"prettier:check": "prettier --check --ignore-unknown .",
"start": "next start",
"seed": "node -r dotenv/config ./scripts/seed.js",
"lint": "next lint"
},
...
実際にここまでの設定をして実際にアプリケーションを起動すると New Relic APM が起動されてサーバーサイドに対してきたリクエストが記録されるようになります。
APM までは計測ができるようになったので最後に Browser Agent を導入します。
Browser Agent の導入
Browser Agent の導入方法についてはいくつかありますが今回は Node.js Agent の API としてある newrelic.getBrowserTimingHeader() を利用して導入を行います。
app/layout.tsx に対して処理を行います。
import '@/app/ui/global.css';
import { inter } from '@/app/ui/font';
import { Metadata } from 'next';
import Script from 'next/script'
import newrelic from 'newrelic';
export const metadata: Metadata = {
title: 'Acme Dashboard',
description: 'The official Next.js Course Dashboard, built with App Router.',
metadataBase: new URL('https://next-learn-dashboard.vercel.sh'),
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const browserTimingHeader = newrelic.getBrowserTimingHeader({
hasToRemoveScriptWrapper: true,
})
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>
{children}
<Script
// We have to set an id for inline scripts.
// See https://nextjs.org/docs/app/building-your-application/optimizing/scripts#inline-scripts
id="nr-browser-agent"
// By setting the strategy to "beforeInteractive" we guarantee that
// the script will be added to the document's `head` element.
strategy="beforeInteractive"
// The body of the script element comes from the async evaluation
// of `getInitialProps`. We use the special
// `dangerouslySetInnerHTML` to provide that element body. Since
// it requires an object with an `__html` property, we pass in an
// object literal.
dangerouslySetInnerHTML={{__html: browserTimingHeader}}
/>
</body>
</html>
);
}
newrelic.getBrowserTimingHeader() で取得した結果を 'next/script' を用いて挿入する形を取っています。
アプリケーションを再起動して取得されているか確認しましょう。
データが表示されていれば無事 Next.js への New Relic Agent の導入は成功になります。
後は実際にアプリケーションを動作させてテレメトリー情報を可視化して利用していければ良いなと思っています。
本記事の内容は以上となります。
Discussion