You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为OpenTelemetry Node.js SDK配置PrometheusExporter导出Trace数据

OpenTelemetry JS:将Trace数据转换为Metrics并导出到Prometheus

首先明确核心点:Prometheus是**指标(Metrics)**采集系统,不直接接收Trace(链路追踪)数据。@opentelemetry/exporter-prometheus是用于导出Metrics的组件,不能直接替换Trace的ConsoleSpanExporter。你需要将Trace数据转换为Metrics后,再通过该Exporter发送给Prometheus,具体流程如下:

一、核心配置流程

  1. 保留Trace采集链路,用NodeTracerProvider处理Span数据
  2. 初始化MeterProvider管理Metrics,关联PrometheusExporter
  3. 通过自定义SpanProcessor监听Span生命周期,将Trace数据转换为Metrics
  4. 配置Prometheus抓取Metrics端点

二、完整代码示例(instrumentation.js)

先确认已安装依赖(若缺失请补充):

npm install @opentelemetry/sdk-trace-node @opentelemetry/sdk-metrics @opentelemetry/api @opentelemetry/exporter-prometheus @opentelemetry/exporter-trace-otlp-console

代码实现:

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { ConsoleSpanExporter } = require('@opentelemetry/exporter-trace-otlp-console');
const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const { trace } = require('@opentelemetry/api');

// 1. 配置Prometheus Metrics导出器
const prometheusExporter = new PrometheusExporter({
  port: 9464, // 自定义端口,默认9464
});

// 2. 初始化MeterProvider并绑定导出器
const meterProvider = new MeterProvider();
meterProvider.addMetricReader(new PeriodicExportingMetricReader({
  exporter: prometheusExporter,
  exportIntervalMillis: 10000, // 每10秒导出一次Metrics
}));
const meter = meterProvider.getMeter('trace-to-metrics-converter');

// 3. 自定义SpanProcessor:监听Span结束事件,转换为Metrics
class TraceMetricsProcessor {
  constructor(meter) {
    // 定义需要的Metrics指标
    this.requestCounter = meter.createCounter('app_requests_total', {
      description: 'Total number of traced requests',
    });
    this.requestDurationHist = meter.createHistogram('app_request_duration_ms', {
      description: 'Duration of traced requests (milliseconds)',
    });
  }

  // Span结束时触发,提取数据生成Metrics
  onEnd(span) {
    // 仅处理业务相关Span(示例:过滤HTTP请求Span)
    if (span.name.includes('HTTP')) {
      const method = span.attributes['http.method'] || 'unknown';
      const statusCode = span.attributes['http.status_code'] || 'unknown';
      const endpoint = span.attributes['http.target'] || 'unknown';

      // 记录请求总数(带标签维度)
      this.requestCounter.add(1, {
        method,
        status_code: statusCode,
        endpoint,
      });

      // 记录请求耗时(Span duration为纳秒,转毫秒)
      const durationMs = span.duration[0] * 1000 + span.duration[1] / 1e6;
      this.requestDurationHist.record(durationMs, {
        method,
        status_code: statusCode,
        endpoint,
      });
    }
  }

  // 实现SpanProcessor接口的其他空方法
  onStart(span, context) {}
  shutdown() { return Promise.resolve(); }
  forceFlush() { return Promise.resolve(); }
}

// 4. 初始化TracerProvider并绑定处理器
const tracerProvider = new NodeTracerProvider();
// 添加自定义Trace转Metrics处理器
tracerProvider.addSpanProcessor(new TraceMetricsProcessor(meter));
// 可选:保留ConsoleSpanExporter查看原始Trace数据
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));

// 注册全局Tracer
tracerProvider.register();

// 测试:模拟业务Span生成
const tracer = trace.getTracer('test-app-tracer');
setInterval(() => {
  const span = tracer.startSpan('HTTP GET /api/user');
  span.setAttribute('http.method', 'GET');
  span.setAttribute('http.target', '/api/user');
  span.setAttribute('http.status_code', 200);
  setTimeout(() => span.end(), Math.random() * 1200);
}, 2000);

三、关键细节说明

  • SpanProcessor的作用:通过onEnd钩子捕获每个Span的结束事件,提取Span的属性(如HTTP方法、状态码、耗时),转换为Prometheus支持的Metrics类型(计数器、直方图)。
  • Metrics端点验证:启动应用后,访问http://localhost:9464/metrics,能看到生成的app_requests_total和app_request_duration_ms指标。
  • Prometheus抓取配置:在prometheus.yml中添加以下配置,即可让Prometheus自动采集指标:
scrape_configs:
  - job_name: 'node-app-trace-metrics'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:9464']

四、常见问题排查

  • 无Metrics生成:检查Span的属性是否正确设置,自定义处理器中的过滤条件是否匹配你的Span名称/属性。
  • Prometheus无法抓取:确认端口未被占用,防火墙允许访问,Prometheus配置的target地址正确。
  • 版本兼容问题:确保所有@opentelemetry/*依赖包版本一致,避免因版本差异导致的API不兼容。

内容的提问来源于stack exchange,提问作者Sergey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:17:07