一个看似微小的追踪规则变化
.NET 10 修改了一条追踪采样规则,这条规则的变化可能悄悄让自定义采样器失效。在 .NET 10 的 ActivitySamplingResult PropagationData 行为中,子活动不再因为父级携带 recorded 标志就自动变成 Recorded。追踪身份仍然会继续传递,但本地采样决定现在占据主导。
这个决定值得当作一份契约来测试。采集器并不需要复现这一行为,而导出器实际上可能把重要部分隐藏在更多配置之后。一个固定的 ActivityContext、一个 ActivityListener,再加上几条断言,就足够验证。
采样结果决定数据收集程度
ActivitySource.StartActivity 只有在已注册的监听器请求创建活动时,才会真正创建活动。监听器返回的采样结果同时说明活动应当收集多少数据。
在 .NET 10 之前,PropagationData 对这张规则表有一个例外:如果父级是 recorded,子级也会变成 recorded。微软改变这一行为,是因为继承的标志与采样结果或 OpenTelemetry 契约并不一致。.NET 10 的兼容性说明现在明确写道:即使父级是 recorded,PropagationData 子活动的 Recorded 和 IsAllDataRequested 都为 false。
两个标志回答不同问题
这个区别在自定义监听器里很重要。Recorded 控制向下游传播的 W3C recorded 位,IsAllDataRequested 则告诉埋点代码是否需要附加详细数据。它们回答的是不同问题,所以强制其中一个并不会自动启用另一个。ActivitySamplingResult 的 API 文档是理解这四种选择的紧凑参考。
测试从一个决策明确的监听器和一个 ID 固定的远程父级开始。监听器返回 PropagationData,父级 ActivityContext 使用固定的 trace ID 和 span ID,并带有 Recorded 标志,isRemote 为 true。随后通过 source.StartActivity 创建名为 receive-message 的子活动,活动类型为 Consumer。
关键断言只针对契约本身
重要的断言围绕契约展开,而不是生成的标识符或墙上时钟时间。子活动不为 null,TraceId 与父级一致,ParentSpanId 等于父级的 SpanId,Recorded 为 false,IsAllDataRequested 也为 false。
子活动存在并延续了追踪,这正是 PropagationData 所请求的结果。它只是没有声称当前进程选择记录或丰富数据。
热门跟贴