使用 OpenTelemetry 监控 Next.js 应用:@vercel/otel 与手动集成双方案实战
发布时间:2026/9/25 4:01:52来源:尧图网络
可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载本文以 highlight.io 开源全栈可观测平台为背景系统讲解如何在 Next.js 应用中接入 OpenTelemetryOTel从开启实验性 instrumentation hook、理解默认 Span 与自定义 Span到通过vercel/otel一键接入或手动基于 Node SDK 精细化配置并说明 Edge 运行时的处理方式与 Highlight 在采集、日志、Session Replay 上的增强能力。读完本文你将能够独立为自己的 Next.js 应用搭建一套 vendor-agnostic 的可观测数据链路并知道如何把它对接到 Highlight 的托管 Collector。Next.js 集成概览可观测性是监控和优化 Web 应用性能的关键。将 OpenTelemetry 集成进 Next.js 应用可以获得关于应用行为的宝贵洞察。本节的目标是在 Collector 已就绪的前提下把 Next.js 应用配置为向 Collector 推送遥测数据。官方对 Next.js 的 OTel 支持基本有两条路线二选一即可使用 Vercel 出品的vercel/otel包上手极快开箱即用手动集成基于opentelemetry/sdk-node等官方 SDK 自行装配灵活度更高。两条路线都依赖 Next.js 的 instrumentation 机制。在 Next.js 15 之前instrumentation 属于实验特性需要显式开启/** type {import(next).NextConfig} */ module.exports { experimental: { instrumentationHook: true, }, };开启后需要在应用根目录注意不是app或pages目录内部创建一个名为instrumentation.ts的文件并导出一个名为register的函数。该函数只在每个 Next.js 服务器实例启动时执行一次因此特别适合做全局注册与初始化类工作——例如注册 OTel SDK、设置全局探针等。从仓库实践看Highlight 的 Next.js SDK 同样遵循这一机制。在 e2e/nextjs/src/instrumentation.ts 中register函数在运行时动态加载highlight-run/next/server并调用registerHighlight(highlightConfig)其中highlightConfig携带projectID、otlpEndpoint、serviceName、environment等 Node 侧选项。动态import的目的正是为了兼容不同运行时的条件加载避免在 Edge 环境中引入 Node 专属依赖。默认 SpanNext.js 开箱自带的遥测开启实验性开关后Next.js 会随请求处理自动产生一批默认 Span。无论你使用vercel/otel还是手动集成这批默认 Span 都可用不过其中一部分仅适用于 App Router另一部分仅适用于 Pages Router。多数默认 Span 会携带一组可用于检索和过滤遥测数据的属性Attributes属性名说明next.span_name与 Span 名称重复next.span_type每种 Span 类型都有唯一标识符next.route请求的路由模式例如/\[param\]/usernext.rsctrue/false该请求是否为 RSCReact Server Components请求例如 prefetchnext.pageApp Router 内部使用的值可以理解为指向某个特殊文件如page.ts、layout.ts、loading.ts等的路由需要特别注意的是next.page的语义它只有在与next.route配对使用时才能作为唯一标识——因为/layout可能同时标识/(groupA)/layout.ts与/(groupB)/layout.ts。常见的默认 Span 包括[http.method] [next.route]fetch[http.method] [http.url]generateMetadata[next.page]resolve page componentsresolve segment modulesstart responseApp Router 专属 Spanrender route (app)[next.route]executing api route (app)[next.route]Pages Router 专属 SpangetServerSideProps[next.route]getStaticProps[next.route]render route (pages)[next.route]自定义 Span给业务打上自己的标记默认 Span 覆盖的是框架层行为业务关键路径则需要自定义 Span 来观测。做法很简单引入 OpenTelemetry API 获取 Tracer然后启动 Span并在合适时机结束 Span。import { trace } from opentelemetry/api; export async function fetchGithubStars() { return await trace .getTracer(next-app) .startActiveSpan(fetchGithubStars, async (span) { try { return await getValue(); } finally { span.end(); } }); }需要留意两点务必结束 Span上例使用try/finally保证无论成功失败都会调用span.end()避免 Span 泄漏导致遥测数据悬挂。遵循语义约定Semantic Conventions自定义 Span 建议遵守 OpenTelemetry 通用 Trace 语义约定让你的 Span 与其他组件、其他厂商的遥测数据和睦相处保证跨服务关联与检索的一致性。Option A接入vercel/otelvercel/otel上手非常简单且在所有 Next.js 可运行的环境中都能工作Vercel 的 Node.js 环境、Edge 运行时以及你自己的自托管环境。安装依赖后核心只有一件事导入包并调用registerOTel函数传入服务名字符串即可import { registerOTel } from vercel/otel; export function register() { registerOTel(next-app); }registerOTel也支持传入配置对象做更细粒度的定制。当前配置接口如下interface Configuration { attributes?: Attributes; attributesFromHeaders?: AttributesFromHeaders; autoDetectResources?: boolean; contextManager?: ContextManager; idGenerator?: IdGenerator; instrumentationConfig?: InstrumentationConfiguration; instrumentations?: InstrumentationOptionOrName[]; logRecordProcessor?: LogRecordProcessor; metricReader?: MetricReader; propagators?: PropagatorOrName[]; resourceDetectors?: DetectorSync[]; serviceName?: string; spanLimits?: SpanLimits; spanProcessors?: SpanProcessorOrName[]; traceExporter?: SpanExporterOrName; traceSampler?: SampleOrName; views?: View[]; }这份配置覆盖了资源探测、采样器、Span 处理器/导出器、传播器、仪器化模块、指标读取器、日志记录处理器等完整装配面意味着即使使用vercel/otel你依然能对遥测管线做深度定制而不必完全受制于默认行为。Option B手动集成vercel/otel之外的另一种选择是手动集成。需要重点强调的是手动集成与 Edge 运行时不兼容。因此我们必须确保只在 Node.js 环境注册 instrumentation 函数export async function register() { if (process.env.NEXT_RUNTIME nodejs) { await import(./instrumentation.node.ts); } }在instrumentation.node.ts中引入 OpenTelemetry Node SDK 及相关类并启动 SDKimport { NodeSDK } from opentelemetry/sdk-node; import { OTLPTraceExporter } from opentelemetry/exporter-trace-otlp-http; import { Resource } from opentelemetry/resources; import { SEMRESATTRS_SERVICE_NAME } from opentelemetry/semantic-conventions; import { SimpleSpanProcessor } from opentelemetry/sdk-trace-node; const sdk new NodeSDK({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: next-app, }), spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter()), }); sdk.start();这段代码的核心动作通过Resource声明服务名SEMRESATTRS_SERVICE_NAME用OTLPTraceExporter指定 OTLP/HTTP 导出器默认指向本机 Collector 的 OTLP HTTP 端点并用SimpleSpanProcessor简单同步处理 Span——适合开发环境生产环境通常建议换成BatchSpanProcessor以批量上报、降低开销。手动集成的价值在于可以做更多事情例如进一步为 Node 应用的其他部分注入自动 instrumentationconst instrumentations getNodeAutoInstrumentations({ opentelemetry/instrumentation-pino: { logHook: (span, record, level) { record[resource.service.name] next-app; span.setAttribute(NEXT_LOG_KEY, NEXT_LOG_VALUE); const attrs span.attributes; for (const [key, value] of Object.entries(attrs)) { record[key] value; } }, // 在自定义键名下记录 Span 上下文 // 该配置可选默认使用 trace_id、span_id 和 trace_flags 作为键名 logKeys: { traceId: traceId, spanId: spanId, traceFlags: traceFlags, }, }, // 为 http 插桩加载自定义配置 opentelemetry/instrumentation-http: { applyCustomAttributesOnSpan: (span) { span.setAttribute(foo2, bar2); }, }, opentelemetry/instrumentation-fs: { enabled: false }, }); registerInstrumentations({ instrumentations, }); const sdk new NodeSDK({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: next-app, }), instrumentations, }); sdk.start();这段示例展示了手动集成的三个进阶点日志与 Trace 关联通过 pino 插桩的logHook把 Span 属性注入日志记录再通过logKeys把trace_id/span_id/trace_flags写入自定义键名使日志与分布式追踪在同一条链路内可互相检索HTTP 插桩定制applyCustomAttributesOnSpan允许在每个 HTTP Span 上追加自定义属性按需启停插桩enabled: false可关闭不需要的插桩如文件系统插桩减少无谓开销。从 Highlight 的源码看其对运行时的判断比示例更防御性在 sdk/highlight-next/src/util/is-node-js-runtime.ts 中只要process.env.NEXT_RUNTIME未定义或等于nodejs即视为 Node 运行时而 register-highlight.ts 在非 Node 运行时只输出一条提示日志而不注册 SDK避免在 Edge 环境误初始化 Node 专属依赖。Manual 配置下的 Edge 支持官方虽然没有正式支持但手动配置理论上可以通过一些手段与 Edge 运行时配合。由于 Vercel 基于 Cloudflare Workers可以借助其waitUntilAPI 来延长 Edge 函数的生命周期确保异步上报在响应返回后仍能完成。Highlight 在其 SDK 中对waitUntilAPI 做了 polyfill 以支持 Edge 运行时因此在 Highlight 集成场景下你无需为 Edge 上报做额外处理。从源码结构看Highlight 的 Next.js SDK 为此做了运行时分层包入口通过条件导出见 sdk/highlight-next/package.json 中exports的edge/edge-light/worker/workerd分支让 Edge 运行时加载独立的server.edge.js同时 server.ts 中PageRouterHighlight/AppRouterHighlight只在 Node 运行时生效并明确对不支持的运行时抛错。此外with-highlight-nodejs-app-router.ts 通过高阶组件Highlight(options)包裹原始 handler在H.runWithHeaders中以METHOD - url命名并携带请求头上下文实现服务端 Trace 与客户端会话的关联。Highlight 如何增强你的可观测性当 Collector 与 Next.js instrumentation hook 都就绪后链路已经基本打通。那么 Highlight 能带来什么增量价值首先Highlight 提供托管 Collector。你无需自建并操心 Collector 的扩展性与高可用——把这些运维负担交给 Highlight 团队你的时间可以更专注于构建应用与交付功能。不止是 OpenTelemetry Node.js SDK其次Highlight 补上了官方 OpenTelemetry Node.js SDK 尚未完善的能力。正如前文提到的官方 SDK 对 Logging 的支持仍处于开发中Highlight 填补了这一空白让你获得与其他主流厂商一致的Logging日志与 Error Tracing错误追踪体验。最突出的差异化能力是Session Replay会话回放。Highlight 投入大量精力将客户端事件与 Span 关联到服务端 Trace 上让你能够直观看到用户在你的应用中的完整操作路径。同时回放中的任何个人数据都会被尽力擦除scrub这同样是 Highlight Collector 默认提供的保护无需你额外做任何工作。请求级关联的实现细节在 Highlight 的 Next.js SDK 中这种全栈关联不止停留在概念层highlight-node.ts 中的H.metrics会把调用方传入的secureSessionId与requestId自动转换为highlight.session_id与highlight.trace_id标签随指标一并上报从而把服务端指标钉在具体会话与 Trace 上instrument-server.ts 包装了 Next.js 服务端的ensureApiPage与findPageComponents方法以参数化路径作为http.route标签记录 API 请求与页面请求的耗时指标——这正是获取参数化请求 URL 作为事务名的一种实现思路该实现灵感源自 Sentry 的 Next.js 集成全流程示例可参考 e2e/nextjs/next.config.mjs通过withHighlightConfig(nextConfig, { apiKey })一行包装即可开启 SDK 的构建期集成。总结回到最初的问题——无论你使用 Vercel 还是自托管使用 Highlight、自建 Collector还是其他任何 OpenTelemetry 兼容厂商……OTel 都是一个极其重要的项目它帮助你保持 vendor-agnostic 的遥测集成。当你想更换供应商时可以显著减少重写与返工的成本。而 Highlight 则在这一标准之上为你提供托管 Collector、完整的日志与错误追踪以及业界领先的 Session Replay 会话级关联体验。实践要点回顾先确认 Collector 就绪再在next.config中开启experimental.instrumentationHookNext.js 15 之前在应用根目录创建instrumentation.ts并导出register()其中完成 OTel SDK 初始化利用默认 Span 及其next.*属性做检索与过滤用自定义 Span记得end()与语义约定覆盖业务路径快速集成选vercel/otel深度定制选手动集成注意NEXT_RUNTIME环境判断与 Edge 不兼容问题将 OTLP 导出器指向 Highlight Collector即可获得托管采集、日志/错误追踪与 Session Replay 的全栈可观测能力。赞分享可观测性后端【免费下载链接】highlighthighlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.项目地址https://gitcode.com/gh_mirrors/hi/highlight点击查看免费下载相关推荐OpenTelemetry eBPF Profiler与OTel Collector集成企业级性能监控的智能解决方案OpenTelemetry eBPF Profiler与OTel Collector集成企业级性能监控的智能解决方案 在当今复杂的企业应用环境中性能监控已成Ornith-1.0-35B代码生成技巧5个提升编程效率的秘诀Ornith 1.0 35B代码生成技巧5个提升编程效率的秘诀 Ornith 1.0 35B是一款开源的智能代码生成模型专为提升开发者编程效率而设计。作为ONext.js与Vercel Analytics集成终极用户行为与性能监控指南Next.js与Vercel Analytics集成终极用户行为与性能监控指南 Next.js作为React框架与Vercel Analytics的集成提供了前端后端Web框架SSR前端构建上一篇洛雪音乐开源音源配置指南多平台音乐聚合解决方案深度解析下一篇Caffe2自定义网络层开发以注意力机制为例的实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网