🤳

Next.js (App Router) に New Relic の Agent を導入する

2024/06/11に公開

この記事は?

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