在使用W3C跟踪上下文时,如何从标头中找出跟踪跨度之间的关系



我一直在阅读W3C跟踪上下文规范,我不知道如何通过查看请求中的标头来获得跨度之间关系的子级。

假设我正确理解处理模型,则第一个服务生成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

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

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

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

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

tracestate使用由一组名称/值对表示的供应商特定数据扩展traceparent。以跟踪状态存储信息是可选的。

如前所述,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来构建父子关系(我在本文中对此进行了介绍(。如果您使用的是不同于System.Diagnostics的框架、中间件或库,并且它不提供上游traceparent,请记住,在它到达新的跨度范围时,您需要存储它。换句话说,在父id/span idtraceparent的更新之前。

最新更新