这个坑值得记一笔。接入 OpenTelemetry 1.27 后看板里每次问答只有一条父 span,检索、重排、模型调用三个子调用的耗时完全没有,父 span 显示 800ms,实际端到端 3.2 秒。
刚开始盯着「采样器只在入口判定,子 span 被判不采」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。子调用没用到带上下文的 tracer;线程池里跑的任务拿不到父上下文;导出器批量发送时进程提前退出,尾部 span 丢了。
上来先确认子 span 的 parent_id 是否存在
python -c "print({'span':'search','parent_id':None})"
接着把 tracer 注入到线程池任务里再跑一次
python worker.py --with-context --trace
然后关闭尾部采样观察子 span 是否出现
python run_otel.py --sampler always_on
进程退出前强制 flush 导出队列
python -c "from opentelemetry import trace;trace.get_tracer_provider().shutdown()"
怎么算真的好了,看的是同一批现象。看板里一次问答能看到三段子 span,父 span 耗时与子调用之和吻合,采样率调整后链路结构不变。
跨线程和跨进程是链路断掉的高发区,上下文要显式传,别指望全局变量能自动带过去。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
