You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤无关联日志的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:43:12