You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js预渲染页面集成New Relic及日志收集问题咨询(含getInitialProps异常)

Next.js 集成 New Relic 实战方案

1. 预渲染页面(SSG/ISR)集成New Relic并捕获所有浏览器错误

预渲染页面绝对不能碰getInitialProps(会直接禁用静态生成),用全局注入的方式搞定客户端监控:

  • 第一步:在pages/_document.js注入New Relic浏览器脚本
    这个文件是服务端渲染的根文档,全局注入完全不影响预渲染:
import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* 替换成你的New Relic配置 */}
          <script
            dangerouslySetInnerHTML={{
              __html: `
                window.NREUM || (NREUM = {});
                NREUM.info = {
                  beacon: 'bam.nr-data.net',
                  errorBeacon: 'bam.nr-data.net',
                  licenseKey: '你的New Relic许可证密钥',
                  applicationID: '你的应用ID',
                  sa: 1
                };
                // 粘贴New Relic官方提供的浏览器监控脚本剩余部分
              `,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
  • 第二步:在pages/_app.js捕获全局错误
    用React的useEffect监听全局错误事件,直接上报到New Relic:
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    // 捕获未处理的全局错误
    window.addEventListener('error', (event) => {
      window.NREUM?.noticeError(event.error);
    });

    // 捕获Promise未处理拒绝
    window.addEventListener('unhandledrejection', (event) => {
      window.NREUM?.noticeError(event.reason);
    });
  }, []);

  return <Component {...pageProps} />;
}

export default MyApp;

2. 同时上报浏览器端+服务端日志(避开getInitialProps)

要覆盖两端,得分开处理:

服务端集成(Node.js环境)

  1. 安装依赖:npm install newrelic
  2. 项目根目录新建newrelic.js配置文件:
'use strict'
exports.config = {
  app_name: ['你的Next.js应用名称'],
  license_key: '你的New Relic许可证密钥',
  logging: { level: 'info' },
  attributes: {
    exclude: [
      'request.headers.cookie',
      'request.headers.authorization',
      // 其他需要排除的敏感字段
    ]
  }
}
  1. 修改package.json启动脚本,让New Relic代理Node进程:
"scripts": {
  "dev": "newrelic-admin run-node next dev",
  "build": "next build",
  "start": "newrelic-admin run-node next start"
}
  1. 手动上报服务端日志:在API路由或getServerSideProps里直接调用New Relic API:
export async function getServerSideProps(context) {
  const newrelic = require('newrelic');
  
  try {
    const data = await fetch('https://api.example.com/data');
    const result = await data.json();
    // 上报自定义成功事件
    newrelic.recordCustomEvent('DataFetchSuccess', { dataCount: result.length });
    return { props: { result } };
  } catch (err) {
    // 上报服务端错误
    newrelic.noticeError(err);
    return { props: { error: err.message } };
  }
}

客户端集成

直接沿用第一部分的全局注入方案,完全不影响预渲染。


3. getInitialProps集成导致页面加载失败的修复

问题根源

getInitialProps会强制页面变成SSR(禁用静态生成),而且如果在里面直接引用New Relic的客户端代码,服务端执行时没有window对象,直接抛出错误导致页面崩溃。

修复方案

优先方案:彻底放弃页面级getInitialProps

改用getStaticProps(SSG)或getServerSideProps(SSR),客户端监控用全局注入的方式,服务端日志用New Relic Node包处理——这是最稳妥的方案,完全不影响预渲染。

迫不得已要用getInitialProps的情况

必须加环境判断,只在服务端执行New Relic逻辑,客户端逻辑移到组件内部:

export async function getInitialProps(context) {
  // 只在服务端执行
  if (context.req) {
    const newrelic = require('newrelic');
    newrelic.recordCustomEvent('PageInit', { path: context.pathname });
  }
  // 客户端逻辑不要写在这里,移到组件的useEffect里
  return { props: {} };
}

但注意:即使这样,页面也无法静态生成,只能走SSR。


内容的提问来源于stack exchange,提问作者Brijesh Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:05:19