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

NestJS集成OpenTelemetry Metrics报错:MetricReader无法重复绑定MeterProvider

NestJS中OpenTelemetry Metrics报错:MetricReader can not be bound to a MeterProvider again

错误信息

MetricReader can not be bound to a MeterProvider again.
    at PeriodicExportingMetricReader.setMetricProducer (/Users//metrics-otel/node_modules/@opentelemetry/sdk-metrics/src/export/MetricReader.ts:93:13)
    at MeterProvider.addMetricReader (/Users/metrics-otel/node_modules/@opentelemetry/sdk-metrics/src/MeterProvider.ts:97:18)
    at new MeterProvider (/Users/metrics-otel/node_modules/@opentelemetry/sdk-metrics/src/MeterProvider.ts:61:14)
    at NodeSDK.start (/Users/metrics-otel/node_modules/@opentelemetry/sdk-node/src/sdk.ts:279:29)
    at bootstrap (/Users/metrics-otel/src/main.ts:6:17)
    at Object.<anonymous> (/Users/metrics-otel/src/main.ts:10:1)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Function.Module._load (node:internal/modules/cjs/loader:960:12)

复现步骤

  • 执行命令nest new project-name创建项目
  • 在src目录下创建metrics.ts文件

相关代码

metrics.ts

/*instrumentation.ts*/
import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import {
  PeriodicExportingMetricReader,
  ConsoleMetricExporter,
} from '@opentelemetry/sdk-metrics';

export const otelSDK = new NodeSDK({
  traceExporter: new ConsoleSpanExporter(),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new ConsoleMetricExporter(),
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

otelSDK.start();

main.ts

import { otelSDK } from './metrics';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  await otelSDK.start();
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

依赖版本

"dependencies": {
  "@opentelemetry/api": "^1.8.0",
  "@opentelemetry/auto-instrumentations-node": "^0.46.1",
  "@opentelemetry/sdk-metrics": "^1.24.1",
  "@opentelemetry/sdk-node": "^0.51.1",
  "@opentelemetry/sdk-trace-node": "^1.24.1"
}

错误原因

问题核心是重复调用了otelSDK.start():

  1. 在metrics.ts中,创建完otelSDK实例后直接执行了otelSDK.start()
  2. 在main.ts的bootstrap函数里,又再次调用await otelSDK.start()

第一次启动SDK时,PeriodicExportingMetricReader已经绑定到对应的MeterProvider;第二次调用start()会尝试重复绑定同一个MetricReader,触发OpenTelemetry的重复绑定校验逻辑,从而抛出错误。

解决方案

只保留一次otelSDK.start()调用即可,两种可选方式:

方式1:移除metrics.ts中的启动代码

修改后的metrics.ts:

/*instrumentation.ts*/
import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import {
  PeriodicExportingMetricReader,
  ConsoleMetricExporter,
} from '@opentelemetry/sdk-metrics';

export const otelSDK = new NodeSDK({
  traceExporter: new ConsoleSpanExporter(),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new ConsoleMetricExporter(),
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});

// 移除这一行:otelSDK.start();

main.ts保持不变,由bootstrap函数统一启动SDK。

方式2:移除main.ts中的启动代码

修改后的main.ts:

import { otelSDK } from './metrics';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  // 移除这一行:await otelSDK.start();
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

metrics.ts保持不变,由模块导入时自动执行启动逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:45:54