.NET 6 Azure Function使用Serilog时Application Insights日志重复
问题:.NET 6 Azure Function中Serilog日志在Application Insights重复记录
我有一个.NET 6版本的Azure Function应用,原本使用Microsoft.Extension.Logging进行日志记录,一切正常。现因需求需支持结构化日志,遂改用Serilog,但配置后发现日志在Application Insights中重复记录。
以下是startup.cs中配置Serilog的代码:
public override void Configure(IFunctionsHostBuilder builder) { var telemetryConfiguration = TelemetryConfiguration.CreateDefault(); telemetryConfiguration.ConnectionString = Settings.ApplicationInsightsConnectionString; // Create and initialize the dependency tracking module var dependencyModule = new DependencyTrackingTelemetryModule(); dependencyModule.Initialize(telemetryConfiguration); // Create the custom telemetry processor var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder; var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>(); telemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next, configuration)); // Build the telemetry processor chain telemetryProcessorChainBuilder.Build(); Log.Logger = new LoggerConfiguration() .WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces) .CreateLogger(); builder.Services.AddSingleton(telemetryConfiguration); builder.Services.AddSingleton(typeof(IAppLogger<>), typeof(AppLogger<>)); // rest of the code... }
若移除以下代码,日志就不会重复(仅显示Serilog的日志),但由于需要自定义遥测处理器,无法移除该代码:
// Create and initialize the dependency tracking module var dependencyModule = new DependencyTrackingTelemetryModule(); dependencyModule.Initialize(telemetryConfiguration); // Create the custom telemetry processor var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder; var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>(); telemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next, configuration)); // Build the telemetry processor chain telemetryProcessorChainBuilder.Build();
问题核心:注册自定义遥测处理器时同时激活了Microsoft Logger,导致日志重复。如何在不激活Microsoft Logger的情况下,为Serilog注册自定义遥测处理器?
解决方案
问题根源
当你初始化DependencyTrackingTelemetryModule或修改TelemetryConfiguration的处理器链时,Azure Functions的默认日志提供者(Microsoft.Extensions.Logging.ApplicationInsights)会自动关联这个配置实例,导致它与Serilog同时向Application Insights写入日志,最终造成重复记录。
解决步骤
通过禁用默认的Application Insights日志提供者,并确保自定义遥测处理器仅作用于Serilog使用的TelemetryConfiguration,即可解决重复问题:
- 禁用默认AI日志提供者
在Startup.cs的Configure方法中,先移除默认的Application Insights日志过滤规则,阻止它输出日志:
builder.Services.Configure<LoggerFilterOptions>(options => { var aiRule = options.Rules.FirstOrDefault(r => r.ProviderName.Equals("Microsoft.Extensions.Logging.ApplicationInsights", StringComparison.OrdinalIgnoreCase)); if (aiRule != null) { options.Rules.Remove(aiRule); } });
- 配置Serilog为唯一日志提供者
在注册服务时,清除所有默认日志提供者,只添加Serilog:
builder.Services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddSerilog(); });
- 完整修改后的Startup.cs代码
public override void Configure(IFunctionsHostBuilder builder) { // 禁用默认的Application Insights日志提供者 builder.Services.Configure<LoggerFilterOptions>(options => { var aiRule = options.Rules.FirstOrDefault(r => r.ProviderName.Equals("Microsoft.Extensions.Logging.ApplicationInsights", StringComparison.OrdinalIgnoreCase)); if (aiRule != null) { options.Rules.Remove(aiRule); } }); var telemetryConfiguration = TelemetryConfiguration.CreateDefault(); telemetryConfiguration.ConnectionString = Settings.ApplicationInsightsConnectionString; // 初始化依赖跟踪模块 var dependencyModule = new DependencyTrackingTelemetryModule(); dependencyModule.Initialize(telemetryConfiguration); // 添加自定义遥测处理器 var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder; var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>(); telemetryProcessorChainBuilder.Use(next => new CustomTelemetryProcessor(next, configuration)); telemetryProcessorChainBuilder.Build(); // 配置Serilog使用带自定义处理器的TelemetryConfiguration Log.Logger = new LoggerConfiguration() .WriteTo.ApplicationInsights(telemetryConfiguration, TelemetryConverter.Traces) .CreateLogger(); // 注册Serilog为唯一日志提供者 builder.Services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddSerilog(); }); builder.Services.AddSingleton(telemetryConfiguration); builder.Services.AddSingleton(typeof(IAppLogger<>), typeof(AppLogger<>)); // 其他代码... }
原理说明
- 禁用默认AI日志提供者后,只有Serilog会向Application Insights输出日志;
- 自定义遥测处理器附加在Serilog使用的
TelemetryConfiguration上,所有Serilog的日志都会经过该处理器处理; - 依赖跟踪模块依然正常工作,不会影响功能。
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

