如何在Next.js中无需自定义服务器低侵入部署OpenTelemetry?
在Next.js中无需自定义服务器部署OpenTelemetry的低侵入方案
可以实现无需自定义服务器部署OpenTelemetry,以下是两种低侵入性的实现方案,避免了手动创建自定义服务器的冗余代码:
方案一:Node.js预加载(最简洁,全版本兼容)
通过Node.js的--require参数在Next.js启动前预加载OpenTelemetry配置,完全不修改框架原有逻辑:
- 创建
opentelemetry.config.js配置文件:
'use strict' const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-otlp-grpc'); const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const exporterOptions = { url: 'http://localhost:4317', }; const traceExporter = new OTLPTraceExporter(exporterOptions); const sdk = new opentelemetry.NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'SigNoz-Nextjs-Example' }), traceExporter, instrumentations: [getNodeAutoInstrumentations({ // 可选:禁用不需要的工具,减少性能开销 '@opentelemetry/instrumentation-fs': { enabled: false } })] }); sdk.start() .then(() => console.log('OpenTelemetry 初始化完成')) .catch(err => console.error('OpenTelemetry 初始化失败', err)); process.on('SIGTERM', () => { sdk.shutdown() .then(() => console.log('OpenTelemetry 已正常终止')) .catch(err => console.error('OpenTelemetry 终止失败', err)) .finally(() => process.exit(0)); });
- 修改
package.json的启动脚本,添加预加载配置:
{ "scripts": { "dev": "NODE_OPTIONS=\"--require ./opentelemetry.config.js\" next dev", "build": "next build", "start": "NODE_OPTIONS=\"--require ./opentelemetry.config.js\" next start" } }
方案二:Next.js官方Instrumentation(App Router推荐)
针对Next.js 13.4+的App Router,使用官方提供的instrumentation钩子,更贴合框架生态:
- 在项目根目录创建
instrumentation.ts(或.js):
import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-otlp-grpc'; import { Resource } from '@opentelemetry/resources'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; export async function register() { // 仅在生产环境初始化,可根据需求调整 if (process.env.NODE_ENV === 'production') { const sdk = new NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'SigNoz-Nextjs-Example' }), traceExporter: new OTLPTraceExporter({ url: 'http://localhost:4317' }), instrumentations: [getNodeAutoInstrumentations()] }); await sdk.start(); console.log('OpenTelemetry 初始化完成'); process.on('SIGTERM', async () => { await sdk.shutdown(); console.log('OpenTelemetry 已正常终止'); process.exit(0); }); } }
- 在
next.config.js中启用instrumentation钩子:
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { instrumentationHook: true, }, }; module.exports = nextConfig;
必要依赖安装
确保安装所有所需的OpenTelemetry包:
npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-otlp-grpc @opentelemetry/resources @opentelemetry/semantic-conventions
注意事项
- 生产环境建议通过环境变量配置 exporter 地址等参数,避免硬编码。
- Page Router 项目优先选择方案一,方案二仅适配App Router的高版本Next.js。
内容的提问来源于stack exchange,提问作者The Devman
相关产品推荐
相关产品推荐

