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

Node.js中OpenTelemetry工具库Trace数据无法同步至Grafana求助

问题

我在Node.js应用中使用OpenTelemetry收集数据时遇到了问题,以下是我的配置:

tracing.js

const { logs, SeverityNumber } = require('@opentelemetry/api-logs');
let otelLogs = logs.getLogger("publisher", "1.1")

const traceExporter = new OTLPTraceExporter({
     url: 'http://localhost:4318/v1/traces',
     headers: { hello: 'OTLPTraceExporter' },
 });

const logExporter = new OTLPLogExporter({
     url: 'http://localhost:4318/v1/logs',
     headers: { hello: 'OTLPLogExporter' },
 });

const provider = new BasicTracerProvider({
    resource: new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: process.env.SERVICE,
    }),
});

provider.addSpanProcessor(new SimpleSpanProcessor(traceExporter));
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.register()

const sdk = new opentelemetry.NodeSDK({
    logRecordProcessor: new SimpleLogRecordProcessor(logExporter),
    traceExporter, // http
    instrumentations: [
        new HttpInstrumentation()
    ],
    resource: new Resource({
        [ SemanticResourceAttributes.SERVICE_NAME ]: process.env.SERVICE,
        [ SemanticResourceAttributes.SERVICE_NAMESPACE ]: "test",
        [ SemanticResourceAttributes.SERVICE_VERSION ]: "1.0",
        [ SemanticResourceAttributes.SERVICE_INSTANCE_ID ]: `my-instance-id-1 ${Date.now() }`,
    }),
    serviceName: "SERVICE"
});

const getTracer = () => {
    return trace.getTracer("default")
}

sdk.start()

module.exports = { getTracer }

publisher.js

const express = require('express')
const app = express()
const port = process.env.PORT || 3001
const { logs, SeverityNumber } = require('@opentelemetry/api-logs');
const otelLogs = logs.getLogger("publisher", "1.1")

const tracer = tracing.getTracer()
app.get('/a', async (req, res) => {
    const message = {
        pattern: {cmd: 'add-recipe'},
        data: {
            id: Date.now().toString(),
            title: "adgadgadgdag",
            description: "aadfadfadfeeeee111",
            creationDate: Date(),
            ingredients: ["adfadf","adfadf"]
        }

    }
    res.send(message)
})

app.listen(port, () => {
    console.log(`${process.env.SERVICE} Running ${port}`)
})
otelLogs.emit({
     severityNumber: SeverityNumber.INFO,
     body: "test publisher otelLogs",
     attributes : {test:"attribute"}
})

当我发起GET请求到localhost:3001/a时,控制台能看到如下Trace输出:

{
  traceId: '55245fd1400262e3774bd2c4ece669b7',
  parentId: undefined,
  traceState: undefined,
  name: 'GET',
  id: 'd93da19364db5f55',
  kind: 1,
  timestamp: 1699968631970000,
  duration: 59399.224,
  attributes: {
    'http.url': 'http://localhost:3001/a',
    'http.host': 'localhost:3001',
    'net.host.name': 'localhost',
    'http.method': 'GET',
    'http.scheme': 'http',
    'http.target': '/a',
    'http.user_agent': 'curl/7.81.0',
    'http.flavor': '1.1',
    'net.transport': 'ip_tcp',
    'net.host.ip': '::ffff:127.0.0.1',
    'net.host.port': 3001,
    'net.peer.ip': '::ffff:127.0.0.1',
    'net.peer.port': 42138,
    'http.status_code': 200,
    'http.status_text': 'OK'
  },
  status: { code: 0 },
  events: [],
  links: []
}

但这条Trace记录没有出现在Grafana中,直接调用otelLogs.emit生成的日志却能正常显示。请问如何让工具库生成的所有数据都同步到Grafana?

解决方案

核心问题是重复初始化了Tracer Provider,导致Http Instrumentation生成的Span无法被NodeSDK正确处理并导出到Grafana。

问题分析

你在tracing.js中手动创建并注册了BasicTracerProvider,之后又初始化了opentelemetry.NodeSDK。NodeSDK会自动创建并管理独立的Tracer Provider,两个实例完全分离:

  • 控制台输出的Span来自手动创建的Provider(你给它配置了ConsoleSpanExporter)
  • 手动Provider的OTLPTraceExporter因资源配置冲突、初始化顺序问题,无法将数据正确发送到Grafana
  • 日志能正常显示,是因为日志导出逻辑仅由NodeSDK管理,没有冲突

修复步骤

  1. 删除手动创建的BasicTracerProvider代码块,完全由NodeSDK统一管理Tracer Provider、导出器和Instrumentation
  2. 明确配置NodeSDK的Span处理器,同时保留控制台输出
  3. 确保getTracer使用SDK初始化后的全局Tracer实例

修改后的tracing.js示例:

const { logs, SeverityNumber } = require('@opentelemetry/api-logs');
const { trace } = require('@opentelemetry/api');
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
const { SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base');
const { SimpleLogRecordProcessor } = require('@opentelemetry/sdk-logs');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');

const traceExporter = new OTLPTraceExporter({
     url: 'http://localhost:4318/v1/traces',
     headers: { hello: 'OTLPTraceExporter' },
 });

const logExporter = new OTLPLogExporter({
     url: 'http://localhost:4318/v1/logs',
     headers: { hello: 'OTLPLogExporter' },
 });

const sdk = new NodeSDK({
    spanProcessor: new SimpleSpanProcessor(traceExporter),
    additionalSpanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
    logRecordProcessor: new SimpleLogRecordProcessor(logExporter),
    instrumentations: [new HttpInstrumentation()],
    resource: new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: process.env.SERVICE,
        [SemanticResourceAttributes.SERVICE_NAMESPACE]: "test",
        [SemanticResourceAttributes.SERVICE_VERSION]: "1.0",
        [SemanticResourceAttributes.SERVICE_INSTANCE_ID]: `my-instance-id-1 ${Date.now()}`,
    }),
});

const getTracer = () => {
    return trace.getTracer("default")
}

sdk.start().catch((err) => {
    console.error('OpenTelemetry SDK初始化失败', err);
});

process.on('SIGTERM', () => {
    sdk.shutdown()
        .then(() => console.log('OpenTelemetry SDK已正常关闭'))
        .catch((err) => console.error('OpenTelemetry SDK关闭出错', err));
});

module.exports = { getTracer }

验证要点

  • 重启应用后发起请求,确认控制台仍有Span输出
  • 检查Grafana的Trace面板,确认Http请求的Span已正常显示
  • 日志导出不受影响,依然能正常出现在Grafana中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:11:02