python - 在 OpenTelemetry 中传播顶级跨度 ID

标签 python fastapi open-telemetry distributed-tracing

我正在尝试让 OpenTelemetry 跟踪与 FastAPI 和请求一起使用。目前,我的设置如下所示:

import requests
from opentelemetry.baggage.propagation import W3CBaggagePropagator
from opentelemetry.propagators.composite import CompositePropagator
from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.b3 import B3MultiFormat
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator

set_global_textmap(CompositePropagator([B3MultiFormat(), TraceContextTextMapPropagator(), W3CBaggagePropagator()]))

app = FastAPI()

FastAPIInstrumentor.instrument_app(app)
RequestsInstrumentor().instrument()

@app.get("/")
async def get_things():
    r = requests.get("http://localhost:8081")

    return {
        "Hello": "world",
        "result": r.json()
    }

/ 端点只是对另一个服务执行 GET 操作,该服务看起来基本上与此服务类似,只是使用一些中间件来记录传入的 header 。

如果我发送这样的请求(httpie 格式),

http :8000 'x-b3-traceid: f8c83f4b5806299983da51de66d9a242' 'x-b3-spanid: ba24f165998dfd8f' 'x-b3-sampled: 1'

我希望下游服务,即被 requests.get("http://localhost:8081") 请求的服务,接收看起来像这样的 header

{
  "x-b3-traceid": "f8c83f4b5806299983da51de66d9a242",
  "x-b3-spanid": "xxxxxxx",  # some generated value from the upstream service
  "x-b3-parentspanid": "ba24f165998dfd8f", 
  "x-b3-sampled": "1"
}

但我得到的基本上正是我发送给上游服务的内容:

{
  "x-b3-traceid": "f8c83f4b5806299983da51de66d9a242",
  "x-b3-spanid": "ba24f165998dfd8f",
  "x-b3-sampled": "1"
}

我一定是遗漏了一些明显的东西,但似乎无法弄清楚到底是什么。

发送 W3C traceparent header 会导致完全相同的情况(只是在下游接收的 header 中带有 traceparent)。任何指针将不胜感激。

编辑 - 我没有使用任何导出器,因为在我们的环境中,Istio 配置为导出跟踪。所以我们现在只关心 HTTP 跟踪。

最佳答案

B3MultiFormat 传播器在将上下文序列化为 HTTP header 时不考虑父跨度 id 字段,因为 X-B3-ParentSpanId 是可选 header https://github.com/openzipkin/b3-propagation#multiple-headers .您可以期望 X-B3-TraceIdX-B3-SpanId 始终存在,但不会出现其余的。

编辑:

您是否正在设置具体的跟踪器提供程序?它看起来不像共享代码段,但我不知道您是否是实际的应用程序代码。如果您不设置 sdk 跟踪器提供程序,即没有在 FastAPI 服务中创建记录跨度,则一切都是空操作。请执行以下操作。

...
from opentelemetry.trace import set_tracer_provider
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource

set_tracer_provider(TracerProvider(
    resource=Resource.create({"serice.name": "my-service"})
))

...

另一个编辑:

OpenTelemetry 不在上下文中存储父跨度 ID https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spancontext .来自 OTEL 的上下文传播客户端库仅限于序列化并仅传递此信息。我认为您不能传播 parentSpanId

关于python - 在 OpenTelemetry 中传播顶级跨度 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70243528/

相关文章:

python - 将值插入空的 multidim。数组

python - 如何找到一行的值连续达到最大值的次数

python-3.x - 如何在FastAPI中将文件多文件上传字段设置为可选字段

azure - 使用 OpenTelemetry 的 Azure 上的 App Insights 中的组件名称不正确

azure - 在 Azure Monitor 中查看 opentelemetry 跟踪

open-telemetry - 从隐式上下文中获取当前事件的跨度

python - PyTorch 相当于 numpy reshape 函数

python - 类中参数的条件或限制?

python - 尝试使用 FastAPI 和 python-docx 库读取 docx 文件 : AttributeError: 'bytes' object has no attribute 'seek' error

python - 使用 UVICORN 启用 https