【问题标题】:Propagate top-level span ID's in OpenTelemetry在 OpenTelemetry 中传播顶级跨度 ID
【发布时间】:2022-01-11 13:06:41
【问题描述】:

我正在尝试让 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 操作,基本上看起来像这个服务,只是使用一些中间件来记录传入的标头。

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

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

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

{
  "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 标头会导致完全相同的情况(只是在下游接收的标头中带有 traceparent)。任何指针将不胜感激。

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

【问题讨论】:

    标签: python fastapi open-telemetry distributed-tracing


    【解决方案1】:

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

    编辑:

    您是否设置了具体的跟踪器提供程序?从共享的 sn-p 看起来不像,但我不知道您是否是实际的应用程序代码。如果您不设置 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

    【讨论】:

    • 感谢您的回答。 “父跨度”如何在服务之间传播?为什么我的 spanid 在传入请求和对下游服务的调用之间保持不变?这似乎不合逻辑,还是我遗漏了什么?
    • 你是说下游服务“localhost:8081”收到的span_id和FastAPI服务收到的span_id一样吗?不应该是这样的。您是否看到“/”路线的任何痕迹?
    • 我根据另一轮详细的外观更新了答案。如果它不能解决问题,请告诉我。
    • 好吧,至少现在我在两种服务中都有不同的 span ID!但是仍然没有明显的方法可以将它们联系在一起,除非我直接从应用程序中导出痕迹,而我实际上并不想这样做。一定有某种方法可以将父跨度 ID 传播到下游服务?
    • 将它们捆绑在一起而不导出痕迹是什么意思。如果您不打算从应用程序/服务中导出跟踪,您如何绑定它们?在 opentelemetry 数据模型中,父 id 是 Span 消息的顶级字段,所有后端都使用它来表示 github.com/open-telemetry/opentelemetry-proto/blob/main/…
    猜你喜欢
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 2022-01-01
    • 2021-08-02
    • 2021-05-27
    • 2022-07-03
    • 2021-10-02
    • 1970-01-01
    相关资源
    最近更新 更多