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环境)
- 安装依赖:
npm install newrelic - 项目根目录新建
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', // 其他需要排除的敏感字段 ] } }
- 修改
package.json启动脚本,让New Relic代理Node进程:
"scripts": { "dev": "newrelic-admin run-node next dev", "build": "next build", "start": "newrelic-admin run-node next start" }
- 手动上报服务端日志:在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
相关产品推荐
相关产品推荐

