【问题标题】:How to figure out the relationship between tracing spans from the headers when using W3C Trace Context使用 W3C 跟踪上下文时如何从标头中找出跟踪范围之间的关系
【发布时间】:2021-01-13 12:53:07
【问题描述】:

我一直在阅读 W3C Trace Context 规范,但我不知道如何仅通过查看请求中的标头来获得跨度之间的子关系。

假设我正确理解了processing model,第一个服务会生成一个traceparent,而后续服务会替换traceparent 中的parentId 以用于下游请求。

所以服务 A 生成一个traceparent 并向服务 B 发送请求:

host: service-b
traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01

服务 B 接收请求,每次更改 parentId 时向服务 C 和服务 D 执行两个下游请求:

host: service-c
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
host: service-d
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01

最后,我的请求中有三个 traceparents

00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01

很容易看出它们都属于trace 0af7651916cd43dd8448eb211c80319c,但是如何弄清楚它们之间的父子关系呢?

我最初的想法是这是使用tracestate 完成的,但规范指出:

tracestate 使用由一组名称/值对表示的特定于供应商的数据扩展了 traceparent。在 tracestate 中存储信息是可选的。

【问题讨论】:

    标签: distributed-tracing


    【解决方案1】:

    正如您之前所说,tracestate 字段仅负责传播特定于供应商的数据。而且traceparent本身并没有携带足够的上下游关系信息。跟踪上下文解决了三个问题:为单个跟踪提供唯一标识符,提供商定的机制来转发特定于供应商的跟踪数据 (tracestate),并提供中介、平台和硬件提供商可以支持的行业标准。如果要建立上游-下游(或父-子)关系,则需要当前跨度范围的traceparent 以及上游的traceparent。看看c#中的一个例子.NET 5

    using System;
    using System.Diagnostics;
    
    var upstreamActivity = new Activity("Upstream");
    
    upstreamActivity.Start();
    Console.WriteLine(upstreamActivity.OperationName);
    Console.WriteLine("traceparent: {0}", upstreamActivity.Id);
    Console.WriteLine("upstream traceparent: {0}", upstreamActivity.ParentId);
    CallChildActivity();
    upstreamActivity.Stop();
    
    void CallChildActivity()
    {
        var downstreamActivity = new Activity("Downstream Dependency");
    
        downstreamActivity.Start();
        Console.WriteLine(downstreamActivity.OperationName);
        Console.WriteLine("traceparent: {0}", downstreamActivity.Id);
        Console.WriteLine("upstream traceparent: {0}", downstreamActivity.ParentId);
        downstreamActivity.Stop();
    }
    

    stdout 将显示如下内容:

    Upstream
    traceparent: 00-192400a99d30ee459dce14655b09bc41-587841dea0e59b47-00
    upstream traceparent:
    
    Downstream Dependency
    traceparent: 00-192400a99d30ee459dce14655b09bc41-d95c56215cddd74c-00
    upstream traceparent: 00-192400a99d30ee459dce14655b09bc41-587841dea0e59b47-00
    

    第一个Activity 的上游traceparent 是空的,这意味着:这是整个跟踪的第一个活动。另一方面,第二种方法有一个不为空的ParentId,所以这是上游活动的标识。请注意,ParentId 一词与 w3c 规范的 parent-id 不同,在 .NET 5 中它代表上游标识。除此之外,parent-id 字段在.NET 5 中称为span-id

    这与stack trace 的概念相同,您需要两个id 来建立父子关系(我在article 中写过)。如果您使用与System.Diagnostics 不同的框架、中间件或库,并且它不提供上游traceparent,请记住,您需要在它到达新的跨度范围时存储它。也就是说,在parent-id/span-idtraceparent更新之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-12
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多