首页 / Next.js 16 入门教程 / 监控与可观测性

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:

  1. 部署 Collector 服务
  2. 配置导出器指向你的后端(Datadog、Grafana 等)
  3. 部署 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(),
}))
  1. 用结构化格式:方便日志系统解析
  2. 包含上下文:用户 ID、请求 ID 等
  3. 分级输出:debug、info、warn、error
  4. 避免敏感信息:不要记录密码、token

可观测性不是一次性工作。随着应用演化,持续完善监控体系,才能在问题影响用户之前发现并解决。