分层采样
了解如何在 .NET 中为 OpenTelemetry 跟踪实现分层抽样
本指南演示了一种在 OpenTelemetry .NET 中实现分层抽样的方法。
什么是分层抽样?
分层抽样是将一个总体划分为互斥的子总体或“层”的一种方法。例如,“查询”总体的层可以是“用户发起的查询”和“程序化查询”。然后,使用概率抽样方法对每个层进行抽样。这确保了所有子总体都得到代表。
实现方法
SDK 通过使用一个自定义的 Sampler 来实现这一点,该 Sampler 内部包含两个 Sampler。根据层,会调用相应的 Sampler。
其中一个先决条件是,用于分层抽样决策的标签(例如 queryType)必须在创建活动时提供。
SDK 使用的是分层整群抽样,也称为“不等概率抽样”。例如,每个子总体的样本量与其在总体中的出现次数不成比例。在此示例中,我们希望确保所有用户发起的查询都得到代表,因此我们对其使用 100% 的采样率,而为程序化查询选择的采样率则低得多。
示例代码
关键组件是自定义的 StratifiedSampler 类
public class StratifiedSampler : Sampler
{
private readonly string _stratifyByTagName;
private readonly Dictionary<string, Sampler> _samplersByStratum;
private readonly Sampler _defaultSampler;
public StratifiedSampler(
string stratifyByTagName,
Dictionary<string, Sampler> samplersByStratum,
Sampler defaultSampler)
: base()
{
_stratifyByTagName = stratifyByTagName;
_samplersByStratum = samplersByStratum;
_defaultSampler = defaultSampler;
}
public override SamplingResult ShouldSample(
in SamplingParameters samplingParameters)
{
ReadOnlySpan<KeyValuePair<string, object>> attributes =
samplingParameters.Tags;
for (int i = 0; i < attributes.Length; i++)
{
if (attributes[i].Key.Equals(_stratifyByTagName,
StringComparison.OrdinalIgnoreCase))
{
string stratum = attributes[i].Value.ToString().ToLowerInvariant();
if (_samplersByStratum.TryGetValue(stratum, out Sampler sampler))
{
Console.WriteLine($"StratifiedSampler handling {stratum} query");
return sampler.ShouldSample(samplingParameters);
}
break;
}
}
return _defaultSampler.ShouldSample(samplingParameters);
}
public override string Description => $"StratifiedSampler: {_stratifyByTagName}";
}
示例输出
运行使用此 Sampler 的应用程序时,您应该会看到类似以下的输出
StratifiedSampler handling userinitiated query
Activity.TraceId: 1a122d63e5f8d32cb8ebd3e402eb5389
Activity.SpanId: 83bdc6bbebea1df8
Activity.TraceFlags: Recorded
Activity.ParentSpanId: 1ddd00d845ad645e
Activity.ActivitySourceName: StratifiedSampling.POC
Activity.DisplayName: Main
Activity.Kind: Internal
Activity.StartTime: 2023-02-09T05:19:30.8156879Z
Activity.Duration: 00:00:00.0008656
Activity.Tags:
queryType: userInitiated
foo: child
Resource associated with Activity:
service.name: unknown_service:Examples.StratifiedSamplingByQueryType
Activity.TraceId: 1a122d63e5f8d32cb8ebd3e402eb5389
Activity.SpanId: 1ddd00d845ad645e
Activity.TraceFlags: Recorded
Activity.ActivitySourceName: StratifiedSampling.POC
Activity.DisplayName: Main
Activity.Kind: Internal
Activity.StartTime: 2023-02-09T05:19:30.8115186Z
Activity.Duration: 00:00:00.0424036
Activity.Tags:
queryType: userInitiated
foo: bar
Resource associated with Activity:
service.name: unknown_service:Examples.StratifiedSamplingByQueryType
这表明两个子总体(层)正在独立抽样,每个层应用不同的采样率。
完整示例
有关包含工作应用程序的完整示例,请参阅 OpenTelemetry .NET 存储库。