我一直在阅读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
的更新之前。