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

如何在SpringBoot+GraphQL中获取OTEL的TraceId与SpanID

解决SpringBoot+GraphQL+OTEL获取TraceId/SpanId全0的问题

问题根源

你拿到全0的TraceId/SpanId,是因为当前代码执行时没有绑定OTEL创建的有效Span上下文——要么是OTEL的GraphQL链路追踪未正确初始化,要么是上下文没有传递到你的Resolver代码中。

正确配置与实现步骤

1. 确保依赖与自动配置生效

首先要引入正确的OTEL依赖,让它自动接管GraphQL的链路追踪:

  • 核心依赖(Maven):
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-spring-boot-starter</artifactId>
        <version>1.28.0</version> <!-- 保持所有OTEL依赖版本一致 -->
    </dependency>
    <dependency>
        <groupId>io.opentelemetry.instrumentation</groupId>
        <artifactId>opentelemetry-spring-graphql-1.10</artifactId>
        <version>1.28.0</version> <!-- 与starter版本严格匹配 -->
    </dependency>
    
  • 配置文件(application.yml)中指定服务名(必须,否则OTEL可能不生成有效Span):
    otel:
      service:
        name: your-graphql-service-name
      traces:
        exporter: logging # 本地测试用logging,生产可改为otlp/zipkin
    

2. 正确获取TraceId/SpanId的代码方式

不要直接用Span.current()(上下文未绑定时会返回无效的默认Span),应该通过OTEL的Tracer实例来获取当前Span:

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class YourQueryResolver {
    private final Tracer tracer;

    @Autowired
    public YourQueryResolver(Tracer tracer) {
        this.tracer = tracer;
    }

    public String yourQueryMethod() {
        Span currentSpan = tracer.currentSpan();
        // 先判断Span是否有效
        if (currentSpan.getSpanContext().isValid()) {
            String traceId = currentSpan.getSpanContext().getTraceId();
            String spanId = currentSpan.getSpanContext().getSpanId();
            // 可直接使用或写入日志
            System.out.printf("TraceId: %s, SpanId: %s%n", traceId, spanId);
        }
        // 业务逻辑
        return "query-result";
    }
}

3. 自动将TraceId/SpanId注入日志(推荐)

手动打印太繁琐,通过OTEL的MDC扩展可以自动将TraceId/SpanId注入日志上下文,无需修改业务代码:

  • 引入日志适配依赖(以Logback为例):
    <dependency>
        <groupId>io.opentelemetry.instrumentation</groupId>
        <artifactId>opentelemetry-logback-mdc-1.0</artifactId>
        <version>1.28.0</version>
    </dependency>
    
  • 修改Logback配置(logback-spring.xml),在日志格式中添加TraceId和SpanId字段:
    <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - traceId:%X{trace_id}, spanId:%X{span_id} - %msg%n</pattern>
            </encoder>
        </appender>
        <root level="info">
            <appender-ref ref="CONSOLE"/>
        </root>
    </configuration>
    
    配置完成后,所有日志都会自动带上有效TraceId和SpanId。

4. 常见排查点

  • 检查OTEL版本是否统一:所有OTEL相关依赖的版本必须一致,否则会出现上下文绑定失败的问题。
  • 确认自定义GraphQL Instrumentation的执行顺序:如果有自定义Instrumentation,需通过@Order(Ordered.HIGHEST_PRECEDENCE)保证OTEL的Instrumentation先执行,确保Span先被创建。
  • 检查OTEL SDK是否被禁用:若配置了otel.sdk.disabled=true,OTEL不会生成任何Span,需确保该配置为false(默认值)。
  • 确保请求通过GraphQL入口触发:直接调用Resolver方法不会触发OTEL的Instrumentation,必须通过GraphQL的HTTP接口发送请求才能生成有效Span。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:48:20