Next.js 16 入门教程
监控与可观测性
本教程共 42 篇 · 第 41 篇 · 更新于 2026-07-30 · 约 6 分钟阅读
Next.jsNext.js 16 入门教程监控OpenTelemetryWeb Vitals可观测性性能追踪
41. 监控与可观测性
本节目标:学会用 OpenTelemetry 监控 Next.js 应用,掌握性能指标追踪和 Web Vitals 归因分析的方法。
为什么需要可观测性
随着应用复杂度增加,仅靠日志很难定位问题。可观测性帮你回答:
- 哪个请求慢?慢在哪?
- 错误发生在哪个组件?
- 用户实际体验如何?
- 哪些指标在恶化?
Next.js 内置了 OpenTelemetry 支持,框架本身已经做了基础埋点。
OpenTelemetry 快速集成
使用 @vercel/otel
这是最简单的集成方式:
npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation
创建 instrumentation.ts:
import { registerOTel } from '@vercel/otel'
export function register() {
registerOTel({ serviceName: 'my-next-app' })
}
注意:
instrumentation.ts放在项目根目录,不在app/或pages/里。如果用src目录,放在src/下。
手动配置
如果需要更多控制,可以手动配置:
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation.node.ts')
}
}
// instrumentation.node.ts
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { resourceFromAttributes } from '@opentelemetry/resources'
import { NodeSDK } from '@opentelemetry/sdk-node'
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'
const sdk = new NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'my-next-app',
}),
spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter()),
})
sdk.start()
自定义 Span
用 OpenTelemetry API 添加自定义追踪:
import { trace } from '@opentelemetry/api'
export async function fetchGithubStars() {
return await trace
.getTracer('nextjs-example')
.startActiveSpan('fetchGithubStars', async (span) => {
try {
const stars = await getValue()
span.setAttribute('github.stars', stars)
return stars
} catch (error) {
span.recordException(error)
throw error
} finally {
span.end()
}
})
}
Next.js 自动埋点
Next.js 自动追踪以下操作:
| Span 名称 | 说明 |
|---|---|
[http.method] [next.route] | 根 span,追踪整个请求 |
render route (app) [next.route] | 路由渲染过程 |
fetch [http.method] [http.url] | fetch 请求 |
executing api route (app) [next.route] | API Route 执行 |
generateMetadata [next.page] | 元数据生成 |
resolve page components | 页面组件解析 |
start response | 首字节发送时间 |
Span 属性
Next.js 添加了一些自定义属性:
next.span_name:span 名称next.span_type:span 类型标识next.route:路由模式next.rsc:是否是 RSC 请求next.page:页面标识
Web Vitals 归因
Web Vitals 归因帮你定位性能问题的具体来源:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
webVitalsAttribution: ['CLS', 'LCP'],
},
}
export default nextConfig
可用的归因指标:
CLS:累积布局偏移,定位哪个元素导致偏移LCP:最大内容绘制,识别 LCP 元素INP:交互到下一次绘制,定位交互延迟原因FCP:首次内容绘制TTFB:首字节时间
注意:这个功能还在实验阶段,不建议在生产环境使用。
测试 OpenTelemetry
本地测试需要一个 OpenTelemetry Collector:
# 用官方开发环境
git clone https://github.com/vercel/opentelemetry-collector-dev-setup
cd opentelemetry-collector-dev-setup
docker compose up
启动应用后,应该能看到根 span 标记为 GET /requested/path。
设置 NEXT_OTEL_VERBOSE=1 可以看到更多 span 信息。
部署
Vercel 部署
Vercel 内置了 OpenTelemetry 支持,按照文档连接你的可观测性提供商即可。
自托管
自托管需要自己搭建 OpenTelemetry Collector:
- 部署 Collector 服务
- 配置导出器指向你的后端(Datadog、Grafana 等)
- 部署 Next.js 应用
实用监控指标
应用层
- 请求量:每秒请求数
- 错误率:5xx 错误占比
- 响应时间:P50、P95、P99 延迟
用户体验
- Core Web Vitals:LCP、INP、CLS
- 页面加载时间:从点击到渲染完成
- 交互响应:用户操作到界面更新
业务层
- 转化率:关键流程完成比例
- 活跃用户:DAU/MAU
- 功能使用:各功能的使用频率
日志最佳实践
// 结构化日志
console.log(JSON.stringify({
level: 'info',
message: '用户登录',
userId: user.id,
timestamp: new Date().toISOString(),
}))
- 用结构化格式:方便日志系统解析
- 包含上下文:用户 ID、请求 ID 等
- 分级输出:debug、info、warn、error
- 避免敏感信息:不要记录密码、token
可观测性不是一次性工作。随着应用演化,持续完善监控体系,才能在问题影响用户之前发现并解决。