opentelemetry python trace 不自动跨进程传递,因 http 请求头默认不携带 trace 上下文,需显式启用传播器并手动注入/提取;属性写入失败多因命名、类型或覆盖问题;di 和异步场景需注意 span 生命周期;exporter 配置须匹配协议与路径。

为什么 opentelemetry-python 的 trace 不会自动跨进程传递
因为 HTTP 请求头默认不携带 trace 上下文,服务间调用时 Tracer 无法从入参中提取 parent span。你看到的每个服务都是独立 root span,根本连不成一条线。
- 必须显式启用传播器(如
TraceContextTextMapPropagator),否则inject()和extract()不生效 - HTTP 客户端(如
requests)需手动注入 headers:调用propagator.inject(carrier=request.headers) - FastAPI/Flask 等框架里,得在中间件里用
propagator.extract(carrier=request.headers)恢复 context - 异步服务(
httpx.AsyncClient)同样要注入,但 carrier 要用dict或MultiDict,不能直接传request.headers对象
span.set_attribute() 写进去了却在 UI 里看不到
属性写入时机不对,或 key 名触发了后端过滤规则。OpenTelemetry Collector 默认会丢弃以 http.、net. 开头但不符合语义约定的属性。
- 优先用标准语义约定字段,比如
span.set_attribute("http.status_code", 404),而不是自造"status" - 自定义属性名避免点号,
"user_id"可以,"user.id"在某些后端(如 Jaeger)会被截断或忽略 - 值类型必须是基本类型(
str/int/bool/float),传datetime或dict会静默失败 - 如果用了
OTEL_RESOURCE_ATTRIBUTES环境变量设 service.name,但代码里又调resource.Resource.create(),后者会覆盖前者——属性就丢了
用 fastapi-injector 或 dependency-injector 时 span 生命周期错乱
依赖注入容器创建的对象生命周期和 span 不对齐,常见表现是 span 提前结束、attribute 写到错误 span、甚至 panic 报 Span is already ended。
该软件是以ecshop作为核心的仿制万表网的商场网站源码。万表网模板 2015最新版整体简洁大气,功能实用,是一款时尚典雅的综合类模板!样式精美的商品分类树,层次分明,分类结构一目了然。首页轮播主广告分别对应切换小广告,商品宣传更到位。独家特色增加顶级频道页面、品牌页面,以及仿京东对比功能,提升网站档次,让您的网站更加高端大气!并且全站采用div+css布局,兼容性良好,更注重页面细节,增加多种j
- 不要在 DI provider 里直接调
tracer.start_span();改用with tracer.start_as_current_span()包裹业务逻辑 - 若需跨多个注入对象传递 span,用
context.get_current()+context.attach()显式传递 context,别依赖“当前 span”自动延续 - 异步依赖(
AsyncProvider)必须确保 await 发生在 span 活跃期内,否则 await 后再 set_attribute 就晚了 - 测试时用
trace.TracerProvider(NoOpTracerProvider())替换真实 provider,否则 mock 不干净会导致 context 泄漏
本地开发时 OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 总连不上
不是地址写错,而是 endpoint 协议和端口不匹配:4318 是 HTTP/gRPC 的默认分界点,但 OTLP/HTTP 必须带 /v1/traces 路径,且 collector 需开启 otlphttp receiver。
立即学习“Python免费学习笔记(深入)”;
- 确认 collector 配置含
receivers: [otlp, otlphttp],且otlphttp:下有endpoint: 0.0.0.0:4318 - Python 端 endpoint 应为
http://localhost:4318/v1/traces(HTTP)或http://localhost:4317(gRPC) - Docker 环境下别用
localhost,改用宿主机网关(host.docker.internal)或 compose network 别名 - 启动 collector 后执行
curl -v http://localhost:4318/v1/status,返回 200 才算通——光 ping 通端口没用
跨服务 trace 最容易卡在 propagation 和 exporter 配置这两步,其他地方出问题,大概率是 context 没传进去,或者传进去了但被中间件/装饰器意外清掉了。









