Quarkus集成OpenTelemetry:重定向时链路追踪丢失问题求助
你的问题核心在于OpenTelemetry的Quarkus集成默认仅从请求头读取traceparent,但第三方重定向只将链路参数放在Cookie中,导致上下文无法自动关联。以下是可行的解决思路:
1. 自定义Cookie感知的Trace Propagator
扩展OpenTelemetry的TextMapPropagator,让它优先从请求头提取链路上下文,若头中不存在则从Cookie读取traceparent:
import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.context.propagation.W3CTraceContextPropagator; import jakarta.ws.rs.core.Cookie; import jakarta.ws.rs.core.HttpHeaders; import java.util.Collections; import java.util.List; import java.util.Map; public class CookieAwareTracePropagator implements TextMapPropagator { private final W3CTraceContextPropagator delegate = W3CTraceContextPropagator.getInstance(); @Override public List<String> fields() { return delegate.fields(); } @Override public <C> void inject(Context context, C carrier, TextMapSetter<C> setter) { // 保留默认的注入逻辑(将traceparent写入请求头) delegate.inject(context, carrier, setter); } @Override public <C> Context extract(Context context, C carrier, TextMapGetter<C> getter) { // 先尝试从请求头提取上下文 Context extractedContext = delegate.extract(context, carrier, getter); // 若头中无有效上下文,尝试从Cookie读取 if (extractedContext == Context.root() && carrier instanceof HttpHeaders headers) { Cookie traceCookie = headers.getCookies().get("traceparent"); if (traceCookie != null) { // 构造模拟请求头载体,让W3C Propagator解析Cookie中的traceparent Map<String, String> fakeHeaderCarrier = Collections.singletonMap("traceparent", traceCookie.getValue()); extractedContext = delegate.extract(context, fakeHeaderCarrier, Map::get); } } return extractedContext; } }
2. 在Quarkus中注册自定义Propagator
通过CDI Producer替换默认的Propagator,确保应用启动时生效:
import io.opentelemetry.context.propagation.TextMapPropagator; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Specializes; @ApplicationScoped public class CustomOtelConfig { @Produces @Specializes public TextMapPropagator customTextMapPropagator() { return new CookieAwareTracePropagator(); } }
3. 清理冗余代码
移除你之前创建的@ServerRequestFilter和手动创建父Span的代码——自定义Propagator会在请求处理的最早期自动完成上下文关联,后续所有由OTel自动生成或你手动创建的Span都会自动关联到父链路。
关键注意事项
- 确认第三方重定向后携带的Cookie名称确实是
traceparent,如果是自定义名称,需修改代码中对应的Cookie键值。 - 确保Quarkus与OpenTelemetry依赖版本兼容:Quarkus 3.x对应OTel 1.28+,Quarkus 2.x对应OTel 1.20+,避免版本冲突导致Propagator不生效。
内容的提问来源于stack exchange,提问作者lummycoder
相关产品推荐
相关产品推荐

