已知父Span的traceId和spanId,如何创建Recording Span?
问题
我要埋点的数据流包含多种带内上下文传播机制(SQS、Kinesis消息、数据库写入条目等)。在手动埋点部分组件时,需要提取上下文并创建能反映这些组件工作内容的Recording Spans。我尝试了以下代码实现:
Span parentSpan = Span.wrap(SpanContext.createFromRemoteParent(traceId, parentSpanId, TraceFlags.getDefault(), TraceState.getDefault())); Context propagatedContext = Context.current().with(parentSpan); Span span = tracer.spanBuilder("please-export-me") .setParent(propagatedContext) .startSpan();
但生成的span为PropagatedSpan类型,导致isRecording属性为false,请问该场景的正确解决方法是什么?
解决方法
问题出在你用Span.wrap()包装远程上下文后,生成的是仅用于传播的非记录型Span(PropagatedSpan),无法用于埋点记录。正确做法是直接将远程上下文的SpanContext传入SpanBuilder作为父级,无需提前包装成Span对象。
修改后的代码如下:
// 直接从远程参数创建SpanContext SpanContext remoteParentContext = SpanContext.createFromRemoteParent( traceId, parentSpanId, TraceFlags.getDefault(), TraceState.getDefault() ); // 直接将SpanContext设置为SpanBuilder的父级,创建可记录的Span Span span = tracer.spanBuilder("please-export-me") .setParent(remoteParentContext) .startSpan();
关键说明
- 基于远程追踪上下文创建子Span时,无需先把
SpanContext包装成Span,SpanBuilder原生支持直接接收SpanContext作为父参数。 - 按上述方式创建的Span是正常的RecordingSpan,
isRecording属性会为true,能够正常记录并导出埋点数据。 - 如果需要将该Span的上下文绑定到当前线程,可在创建后注入上下文并使用Scope管理:
Context currentContext = Context.current().with(span); try (Scope scope = currentContext.makeCurrent()) { // 执行需要追踪的业务逻辑 } finally { span.end(); }
内容的提问来源于stack exchange,提问作者kenny_k
相关产品推荐
相关产品推荐

