如何在OTEL与Azure Monitor Exporter .NET中按级别过滤日志/追踪至指定目标
解决Serilog结合OTEL AzureMonitorExporter的分级日志/追踪过滤问题
一、日志部分:通过Serilog原生Sink实现级别过滤
既然AzureMonitorExporter没有直接的过滤配置项,直接用Serilog的Sink级别控制就能满足需求,同时绕开OTEL的导出限制:
- Stdout输出:配置
ConsoleSink,不设置级别过滤,默认接收所有日志级别.WriteTo.Console() - SEQ输出:配置SEQ Sink时,指定最低级别为
Information.WriteTo.Seq("http://your-seq-url", restrictedToMinimumLevel: LogEventLevel.Information) - Application Insights日志输出:使用Serilog的
ApplicationInsightsSink,直接限定最低级别为Warning,只传输符合要求的日志以减少 ingestion 成本.WriteTo.ApplicationInsights(TelemetryConfiguration.CreateDefault(), TelemetryConverter.Traces, restrictedToMinimumLevel: LogEventLevel.Warning)
二、追踪/指标/依赖项部分:用OTEL自定义Processor过滤
针对OTEL导出的追踪、指标、依赖项,通过自定义Processor实现级别过滤:
1. 自定义SpanProcessor过滤追踪内容
创建自定义SpanProcessor,在Span结束时判断状态或属性,过滤掉低级别内容:
public class WarningLevelSpanProcessor : BaseProcessor<Activity> { public override void OnEnd(Activity activity) { // 根据Span状态或自定义标签判断是否保留 if (activity.Status != ActivityStatusCode.Error && !activity.Tags.Any(t => t.Key == "log.level" && t.Value.ToString() is "Warning" or "Error" or "Fatal")) { activity.SetTag("otel.status_code", "DROPPED"); return; } base.OnEnd(activity); } }
在OTEL TracerProvider配置中添加该Processor:
services.AddOpenTelemetry() .WithTracing(tracing => tracing .AddSource("YourAppSource") .AddAzureMonitorTraceExporter(options => { options.ConnectionString = "Your-AI-Connection-String"; }) .AddProcessor(new WarningLevelSpanProcessor()));
2. 指标过滤
通过OTEL的View筛选需要的指标,减少不必要的 ingestion:
services.AddOpenTelemetry() .WithMetrics(metrics => metrics .AddView("your-target-metric", new MetricStreamConfiguration { Filter = (metric) => // 根据指标标签设置过滤条件,比如只保留错误类指标 metric.Labels.Any(l => l.Key == "status" && l.Value == "error") }) .AddAzureMonitorMetricExporter(options => { options.ConnectionString = "Your-AI-Connection-String"; }));
三、额外说明
如果一定要用OTEL的LogExporter处理日志,可参照SpanProcessor的逻辑自定义LogRecordProcessor,过滤掉Warning以下级别的日志记录;另外确保Serilog全局最小级别设为Verbose,避免全局过滤影响Stdout的全量输出。
内容的提问来源于stack exchange,提问作者joacar
相关产品推荐
相关产品推荐

