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

OpenTelemetry中Span链路关联报错:Context对象无trace_id属性

问题:OpenTelemetry Span链路关联报错AttributeError: 'Context' object has no attribute 'trace_id'

尝试为Span添加关联链路时,按文档常规方式无法生效,始终抛出错误:AttributeError: 'Context' object has no attribute 'trace_id'

复现代码

from opentelemetry import trace
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from shared_functionality.common.observability import make_global_tracer

make_global_tracer()
tracer = trace.get_tracer(__name__)

def message_broker_consumer_runner():
    with tracer.start_as_current_span(name=f"consumer_runner.{None}") as consume_span:
        carrier = {}
        TraceContextTextMapPropagator().inject(carrier)
        return carrier

def api_gateway():
    with tracer.start_as_current_span(name=f"api_gateway.{None}") as consume_span:
        carrier = {}
        TraceContextTextMapPropagator().inject(carrier)
        return carrier

def update_info(__trace_propagator):
    print(f"{__trace_propagator=}")

def end(consumer_runner_carrier):
    print(f"{consumer_runner_carrier=}")
    consumer_runner_span = trace.NonRecordingSpan(
        TraceContextTextMapPropagator().extract(consumer_runner_carrier)
    )
    consumer_runner_context = consumer_runner_span.get_span_context()
    with tracer.start_as_current_span(
        name="trigger_update.info",
        context=api_gateway(),  # 错误:传入了carrier字典而非Context对象
        links=[
            trace.Link(consumer_runner_context)
        ],
    ) as msg_span:
        update_info(
            __trace_propagator=msg_span.get_span_context()
        )

if __name__ == "__main__":
    end(message_broker_consumer_runner())

错误信息

consumer_runner_carrier={'traceparent': '00-624066a40219dec50ed88de4feb4ee7a-1be9a825202fa729-01'}
__trace_propagator=SpanContext(trace_id=0x7ae344302d28c0000ea8d4b5457aff39, span_id=0x851a6758cb28f8b7, trace_flags=0x01, trace_state=[], is_remote=False)
Exception while exporting Span batch.
Traceback (most recent call last):
  ...
AttributeError: 'Context' object has no attribute 'trace_id'

使用版本

Python 3.11.4

opentelemetry-api                         1.20.0
opentelemetry-distro                      0.41b0
opentelemetry-sdk                         1.20.0
...(其余相关依赖版本略)

问题核心

通过PyCharm调试器可通过非常规方式获取trace_id并实现关联,但该方式不规范,求正确的Span链路关联实现方式。


解决方案

错误原因分析

  1. context参数传值错误:tracer.start_as_current_span的context参数需要接收OpenTelemetry的Context对象,但代码中传入了api_gateway()返回的carrier字典({'traceparent': ...}),导致后续链路处理时类型不匹配,触发报错。
  2. NonRecordingSpan冗余使用:TraceContextTextMapPropagator().extract()直接返回Context对象,无需包装为NonRecordingSpan,可直接从该Context中提取SpanContext用于创建Link。

修正后的代码

from opentelemetry import trace
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from shared_functionality.common.observability import make_global_tracer

make_global_tracer()
tracer = trace.get_tracer(__name__)

def message_broker_consumer_runner():
    with tracer.start_as_current_span(name="consumer_runner") as consume_span:
        carrier = {}
        TraceContextTextMapPropagator().inject(carrier)
        return carrier

def api_gateway():
    with tracer.start_as_current_span(name="api_gateway") as consume_span:
        carrier = {}
        TraceContextTextMapPropagator().inject(carrier)
        # 从carrier中提取Context对象返回,而非直接返回carrier
        return TraceContextTextMapPropagator().extract(carrier)

def update_info(__trace_propagator):
    print(f"{__trace_propagator=}")

def end(consumer_runner_carrier):
    print(f"{consumer_runner_carrier=}")
    # 直接从carrier提取Context,再获取SpanContext
    consumer_runner_context = TraceContextTextMapPropagator().extract(consumer_runner_carrier)
    consumer_runner_span_context = trace.get_current_span(consumer_runner_context).get_span_context()
    
    # 获取api_gateway的Context对象
    api_gateway_context = api_gateway()
    
    with tracer.start_as_current_span(
        name="trigger_update.info",
        context=api_gateway_context,  # 传入正确的Context对象
        links=[
            trace.Link(consumer_runner_span_context)  # 使用SpanContext创建Link
        ],
    ) as msg_span:
        update_info(
            __trace_propagator=msg_span.get_span_context()
        )

if __name__ == "__main__":
    end(message_broker_consumer_runner())

关键修正点

  • 调整api_gateway返回值:将返回carrier改为返回从carrier提取的Context对象,确保start_as_current_span的context参数类型正确。
  • 简化SpanContext提取:直接从extract()返回的Context中获取当前Span的SpanContext,去掉冗余的NonRecordingSpan包装。
  • 规范Link创建:使用SpanContext对象创建trace.Link,符合OpenTelemetry的链路关联规范。

内容的提问来源于stack exchange,提问作者kchawla-pi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:01:18