升级@opentelemetry/exporter-trace-otlp-grpc后出现连接未建立错误
问题:升级OpenTelemetry API后出现PeriodicExportingMetricReader连接错误
原本运行正常的TypeScript服务,可将指标与追踪数据导出到OpenTelemetry Docker容器,升级至最新API后出现连接错误,问题集中在新API方法PeriodicExportingMetricReader。
OTel Collector配置
receivers: otlp: protocols: grpc: exporters: prometheus: endpoint: '0.0.0.0:8889' namespace: B2B metric_expiration: 525600m jaeger: endpoint: jaeger:14250 tls: insecure: true processors: batch: extensions: health_check: pprof: endpoint: :1888 zpages: endpoint: :55679 service: extensions: [pprof, zpages, health_check] telemetry: logs: level: "info" development: true encoding: "json" pipelines: traces: receivers: [otlp] processors: [batch] exporters: [jaeger] metrics: receivers: [otlp] exporters: [prometheus]
项目包依赖配置
{ "@opentelemetry/api": "^1.3.0", "@opentelemetry/api-metrics": "^0.33.0", "@opentelemetry/host-metrics": "^0.31.0", "@opentelemetry/sdk-metrics": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", "@opentelemetry/exporter-metrics-otlp-grpc": "^0.35.1" }
核心实现代码
export async function startTracing() { try { const collectorOptions = { url: `grpc://localhost:4317`, }; const traceExporter = new OTLPTraceExporter(collectorOptions); const metricExporter = new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter(collectorOptions), exportIntervalMillis: 5000, }); const sdk = new NodeSDK({ resource: new Resource(monitoringAttributes), traceExporter: traceExporter, metricReader: metricExporter, spanProcessor: new BatchSpanProcessor(traceExporter, { scheduledDelayMillis: 500, }), instrumentations: [ new HttpInstrumentation(), new ExpressInstrumentation(), ], }); await sdk .start() .then(() => console.log('Tracing initialized')) .catch((error) => console.log('Error initializing tracing', error)); // gracefully shut down the SDK on process exit process.on('SIGTERM', () => { sdk .shutdown() .then(() => console.log('Tracing terminated')) .catch((error) => console.log('Error terminating tracing', error)) .finally(() => process.exit(0)); }); } catch (e) { console.log('startTracing. error occurred', e); } }
错误日志
2023-03-01 16:51:13 Service request { 2023-03-01 16:51:13 resourceMetrics: [ 2023-03-01 16:51:13 { resource: [Object], schemaUrl: undefined, scopeMetrics: [Array] } 2023-03-01 16:51:13 ] 2023-03-01 16:51:13 } 2023-03-01 16:51:13 {"stack":"Error: PeriodicExportingMetricReader: metrics export failed (error Error: 14 UNAVAILABLE: No connection established)\n at PeriodicExportingMetricReader._doRun (/app/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:122:13)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at PeriodicExportingMetricReader._runOnce (/app/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:94:7)","message":"PeriodicExportingMetricReader: metrics export failed (error Error: 14 UNAVAILABLE: No connection established)","name":"Error"}
排查线索
- 版本兼容性问题:当前
sdk-metrics(1.8.0)和exporter-metrics-otlp-grpc(0.35.1)版本不匹配。OpenTelemetry的SDK与exporter版本需严格对齐,建议将所有OpenTelemetry相关包统一升级到同一主版本(如1.x系列,0.35.x属于旧版本,与1.x不兼容)。 - 网络连接问题:
- 若服务运行在Docker容器中,
localhost:4317指向容器内部而非宿主机,需替换为Docker服务名称(如otel-collector:4317,前提是OTel Collector在同一Docker网络)或宿主机IP。 - 检查OTel Collector的OTLP gRPC端口(4317)是否正常监听,可通过
docker exec <collector-container> netstat -tulpn验证端口状态。
- 若服务运行在Docker容器中,
- Exporter配置格式:新版本
OTLPMetricExporter可能要求使用endpoint字段而非url,同时显式指定不安全连接(未启用TLS时):const collectorOptions = { endpoint: 'otel-collector:4317', credentials: grpc.credentials.createInsecure(), }; - 权限与防火墙:检查服务容器是否有权限访问OTel Collector端口,宿主机或Docker网络是否有防火墙规则拦截4317端口的gRPC流量。
- 初始化校验:确认
PeriodicExportingMetricReader是否正确关联到SDK的metricReader字段,当前写法正确,但需排查是否存在重复初始化或配置冲突。
内容的提问来源于stack exchange,提问作者Laurence Fass
相关产品推荐
相关产品推荐

