父Trace未采集时,如何阻止子OpenTelemetry Trace被采集?
解决方案:过滤健康检查相关的所有Trace(含子Trace)
问题根源
你当前使用的AspNetCoreInstrumentation.Filter仅阻止创建健康检查请求的父Activity,但健康检查流程中触发的数据库操作、自定义Activity等,由于没有父Activity的上下文,ParentBasedSampler会使用配置的根采样器(AlwaysOnSampler)进行采样,导致这些子Trace仍然被导出。
可行方案
方案1:在健康检查请求上下文里注入"不采样"的Activity
通过创建一个标记为**丢弃(Drop)**的临时Activity并设置为当前上下文,让后续所有子操作继承这个采样决策,从而阻止子Trace的生成。
修改你的过滤类:
public static class AspnetCoreOtelFilter { public static bool Filter(HttpContext httpContext) { var healthPaths = new[] { "/health/liveness", "/health/readiness", "/health/details" }; if (healthPaths.Contains(httpContext.Request.Path.ToString())) { // 创建临时Activity并标记为不采样,让后续操作继承该决策 using var dummyActivity = new Activity("HealthCheck.Dummy") .SetSamplingPriority(ActivitySamplingResult.Drop); Activity.Current = dummyActivity; return false; // 阻止创建AspNetCore的父Activity } return true; } }
方案2:使用SuppressInstrumentationScope临时禁用追踪
在健康检查的具体逻辑中,使用OpenTelemetry提供的SuppressInstrumentationScope,直接禁止这段代码块内的所有追踪操作:
修改/health/details的实现:
app.MapGet("/health/details", () => { using var suppressScope = OpenTelemetry.SuppressInstrumentationScope.Begin(); // 此代码块内的所有操作(包括数据库检查、自定义Activity)都不会生成Trace using var activity = source.StartActivity("health.detail"); // 此Activity会返回null return "all fine"; });
方案3:自定义Sampler过滤健康检查相关Trace
如果需要更全局的控制,可以实现自定义Sampler,检查Activity的属性或来源,过滤健康检查相关的Trace:
public class HealthCheckSampler : Sampler { private readonly Sampler _innerSampler; public HealthCheckSampler(Sampler innerSampler) { _innerSampler = innerSampler; } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { // 检查是否是健康检查相关的操作 if (samplingParameters.Name.Contains("health", StringComparison.OrdinalIgnoreCase) || samplingParameters.Attributes?.Any(kv => kv.Key == "http.path" && kv.Value.ToString().StartsWith("/health")) == true) { return new SamplingResult(SamplingDecision.Drop); } return _innerSampler.ShouldSample(samplingParameters); } }
然后修改TracerProvider配置:
.SetSampler(sp => new ParentBasedSampler(new HealthCheckSampler(new AlwaysOnSampler())))
验证测试
修改你的测试方法,移除Ignore标记,执行测试后exportedItems.Count应该为0,说明所有健康检查相关的Trace都被成功过滤。
内容的提问来源于stack exchange,提问作者Pitming Sir
相关产品推荐
相关产品推荐

