Node.js OpenTelemetry 监控实战:指标采集与导出完整教程

用 OpenTelemetry 为 Node.js 应用建立指标监控:自动 HTTP 指标、Counter/UpDownCounter/Gauge/Histogram 四种仪器用法、指标命名规范,以及通过 OTLP 导出到观测云实现看板与告警。附 Express 完整代码示例。

最佳实践
Node.js OpenTelemetry 监控实战:指标采集与导出完整教程封面

Node.js 的 OpenTelemetry 指标接入以 @opentelemetry/sdk-metrics 为核心,配合自动埋点包即可获得 HTTP 层指标,再用四种仪器补充业务指标——JS 生态的自动埋点覆盖 Express、Fastify、Koa 等主流框架,接入成本极低。

核心要点速览

  • 自动埋点包一行注册,HTTP 请求数、耗时自动产出;
  • 业务指标四种仪器:Counter 计数、UpDownCounter 水位、Gauge 瞬时、Histogram 分布;
  • 指标经 OTLP 周期性导出(默认 60s);
  • 端点指向观测云 DataKit 即完成监控闭环。

初始化指标 SDK

const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { Resource } = require('@opentelemetry/resources');

const exporter = new OTLPMetricExporter({
  url: 'http://datakit-host:4318/v1/metrics',
});
const meterProvider = new MeterProvider({
  resource: new Resource({ 'service.name': 'web-frontend' }),
  readers: [new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 30000 })],
});
const meter = meterProvider.getMeter('web-frontend');

注意 NodeSDK(@opentelemetry/sdk-node)可以一行同时初始化链路+指标,新项目推荐直接使用。

自动 HTTP 指标

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

const sdk = new NodeSDK({
  metricReader: new PeriodicExportingMetricReader({ exporter }),
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

Express 的每个路由自动产生请求计数与耗时分布指标,路由参数自动低基数化(/user/:id 而非 /user/12345)。

四种业务指标写法

// Counter:注册总数
const signups = meter.createCounter('user.signups.total');
signups.add(1, { plan: 'pro' });

// UpDownCounter:当前活跃会话
const sessions = meter.createUpDownCounter('sessions.active');
sessions.add(1);            // 登录
sessions.add(-1);           // 登出

// Gauge:当前配置版本之类的瞬时值
const queueDepth = meter.createGauge('jobs.queue.depth');
// 或用 Observable Gauge 回调采集:observableQueue.observe(result => ...)

// Histogram:任务处理耗时分布
const jobDuration = meter.createHistogram('jobs.duration', { unit: 's' });
jobDuration.record(elapsedSeconds, { job_type: 'email' });

命名纪律:点分小写、带单位、属性只放聚合维度(套餐、任务类型),用户 ID 这类高基数值永远不进指标——留给链路与日志。

Node.js 特有的注意点

  • 异步上下文:Promise 链、async/await 由 AsyncLocalStorage 自动跟踪,但事件发射器(EventEmitter)跨边界时需检查上下文是否延续;
  • 进程退出process.on('SIGTERM', () => sdk.shutdown()) 必须加,否则最后一波指标丢失;
  • 单进程多实例:PM2 集群模式下每个进程独立上报,后端按实例标签区分,聚合时留意。

观测云落地:从指标到告警一站完成

exporter 的 URL 指向观测云 DataKit(HTTP 4318),指标自动进入观测云:指标模块查数、场景视图搭看板、监控器配阈值/突变告警,通知走钉钉/企微/飞书。Node.js 应用同时开启链路追踪后,指标异常可直接下钻到具体请求链路。

常见问题(FAQ)

Q:自动埋点和我手写的指标会冲突吗? 不会,自动指标走框架层,手写指标走业务层,名称空间不同;但注意别对同一件事重复计数。

Q:exportIntervalMillis 设多少? 默认 60s,业务监控够用;告警敏感场景可降到 15-30s,再低收益递减。

Q:可以只导出指标不导出链路吗? 可以,分别配置 reader 与 tracer provider,互不影响。

Q:TypeScript 项目有额外配置吗? 类型定义齐全,直接 import 即可;自动埋点需在应用代码之前加载(--require ./tracing.js 启动参数)。

系列阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台