opentelemetry-java嵌套Span场景下SERVER Span未导出问题
问题:WildFly中SmallRye OpenTelemetry隐式SERVER Span无法导出(嵌套显式Span时)
背景
在WildFly应用服务器中,我们通过SmallRye OpenTelemetry使用opentelemetry-java。SmallRye OpenTelemetry会通过ContainerRequestFilter/ContainerResponseFilter为所有Jakarta REST请求隐式创建SpanKind.SERVER类型的Span。
异常现象
- 仅返回字符串的简单REST端点,隐式Span能正常创建并导出;
- 当端点方法创建嵌套显式Span时,过滤器生成的隐式Span无法导出。
测试端点代码
@GET @Produces(MediaType.TEXT_PLAIN) @Path("/test") public String testOpentelemetry(@QueryParam("question") String question) { Span span = tracer.spanBuilder("explicit span") .setAttribute("com.acme.string-key", "value") .startSpan(); try { String answer; try { span.setAttribute("com.acme.question", "question"); span.addEvent(question); answer = question + " received"; span.setStatus(StatusCode.OK); } catch (Exception e) { e.printStackTrace(); span.recordException(e); span.setStatus(StatusCode.ERROR); answer = "My failure reason is:\n\n" + e.getMessage(); } span.addEvent(answer); return answer; } finally { span.end(); } }
调试信息
调试SdkSpan类时,可见endInternal(long endEpochNanos)被调用,隐式Span已结束,但始终未导出;注释掉显式Span相关代码后,隐式Span又能正常导出。
解答
问题核心是显式Span没有正确关联到隐式SERVER Span的上下文,导致OpenTelemetry的Span处理器无法正确识别父子Span关系,进而干扰了隐式Span的导出逻辑。
具体解决要点:
- 绑定父Span上下文:创建显式Span时,必须继承当前请求线程中的SERVER Span上下文,否则显式Span会被当成根Span,打乱整个链路的追踪逻辑。修改代码如下:
Span span = tracer.spanBuilder("explicit span") .setParent(Context.current()) // 关联到当前隐式SERVER Span的上下文 .setAttribute("com.acme.string-key", "value") .startSpan();
- 确保生命周期顺序:你的代码中已经在
finally块中调用span.end(),这部分是正确的——显式Span必须在隐式SERVER Span结束前完成收尾,否则会影响父Span的状态记录。
SmallRye OpenTelemetry的SERVER Span是绑定到Jakarta REST请求的线程上下文的,所有显式Span必须继承这个上下文,才能让整个调用链路被正确追踪、聚合和导出。
内容的提问来源于stack exchange,提问作者jasondlee
相关产品推荐
相关产品推荐

