如何过滤无关联日志的OpenTelemetry追踪,避免生成空追踪?
问题描述
我有一个启用了OpenTelemetry的标准Weather Api示例控制器,代码如下:
using OpenTelemetry; using OpenTelemetry.Trace; var Builder = WebApplication.CreateBuilder(args); Builder.Logging.SetMinimumLevel(LogLevel.Warning); // Add services to the container. _ = Sdk .CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation() .AddConsoleExporter() .Build(); Builder.Services.AddControllers(); var App = Builder.Build(); // Configure the HTTP request pipeline. App.MapControllers(); App.Run();
我已将日志最低级别设置为Warning,因此控制台不会打印任何日志。但调用Weather API接口时,OpenTelemetry仍会创建并向控制台打印追踪数据:
Activity.TraceId: 1d2d6b56be7a8051011388a35cf5f993 Activity.SpanId: 6a3ada20893b840c Activity.TraceFlags: Recorded Activity.DisplayName: GET WeatherForecast Activity.Kind: Server Activity.StartTime: 2024-12-03T12:26:43.2111251Z Activity.Duration: 00:00:00.0670580 Activity.Tags: server.address: localhost server.port: 5214 http.request.method: GET url.scheme: http url.path: /WeatherForecast network.protocol.version: 1.1 user_agent.original: PostmanRuntime/7.43.0 http.route: WeatherForecast http.response.status_code: 200 Instrumentation scope (ActivitySource): Name: Microsoft.AspNetCore Resource associated with Activity: telemetry.sdk.name: opentelemetry telemetry.sdk.language: dotnet telemetry.sdk.version: 1.10.0 service.name: unknown_service:Test.Asp.Net
请问是否可以禁用该行为?如果追踪为空(即无关联日志),我希望不创建并打印这类追踪数据。
解决方案
可以通过两种核心方式实现你的需求:
1. 自定义采样器过滤空追踪
OpenTelemetry的采样器独立于日志级别控制,可通过自定义逻辑决定是否记录Span。你可以实现采样规则,仅保留满足“非空追踪”条件的Span。
自定义采样器代码
public class EmptyTraceSampler : Sampler { private readonly Sampler _baseSampler; public EmptyTraceSampler(Sampler baseSampler) { _baseSampler = baseSampler; } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { var baseResult = _baseSampler.ShouldSample(samplingParameters); // 这里替换为你的"非空追踪"判断逻辑,示例以请求状态码或日志关联为依据 bool needKeep = CheckIfNeedKeepTrace(samplingParameters); return needKeep ? baseResult : new SamplingResult(SamplingDecision.Drop); } private bool CheckIfNeedKeepTrace(in SamplingParameters samplingParameters) { // 示例1:仅保留非200状态码的请求追踪 if (samplingParameters.Attributes.TryGetValue("http.response.status_code", out var statusCode)) { return (int)statusCode != 200; } // 示例2:可扩展为检查是否有关联日志(需结合日志上下文实现) // return LogContext.HasLogsAboveLevel(LogLevel.Warning); return false; } }
集成到TracerProvider
修改TracerProvider构建代码,替换默认采样器:
_ = Sdk .CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation() .SetSampler(new EmptyTraceSampler(new AlwaysOnSampler())) .AddConsoleExporter() .Build();
2. 配置AspNetCore Instrumentation过滤规则
直接通过AspNetCoreInstrumentationOptions过滤掉不需要的请求Span,比如仅保留异常或特定状态的请求:
_ = Sdk .CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation(options => { options.Filter = context => { // 仅保留非200状态码或有异常的请求 return context.Response.StatusCode != 200 || context.Exception != null; }; }) .AddConsoleExporter() .Build();
关键说明
日志级别设置仅控制日志输出,和OpenTelemetry的Trace采样是两个独立的控制流程,因此修改日志级别不会影响Trace的生成和导出。你需要根据自身业务对“空追踪”的定义,调整采样器或过滤规则的判断逻辑。
内容的提问来源于stack exchange,提问作者Athena
相关产品推荐
相关产品推荐

