.NET6 Azure Function隔离版V4集成Autofac与Serilog日志重复问题
Azure Functions 隔离版中Serilog日志重复及日期重复问题
使用的技术栈
- .NET6环境下的Azure Function(隔离版)V4
- Autofac作为依赖注入(DI)引擎
- Serilog作为日志引擎
现有简化代码
Log.Logger = LoggerConfigurationFactory .GetLoggerConfiguration(LogEventLevel.Debug) .CreateLogger(); IConfigurationRoot configurationRoot = GetConfiguration(); IHost host = new HostBuilder() .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureFunctionsWorkerDefaults() .ConfigureServices(services => { services.Remove( services.FirstOrDefault(s => s.ServiceType == typeof(Microsoft.Extensions.Logging.ILoggerFactory))); services.Remove( services.FirstOrDefault(s => s.ServiceType == typeof(Microsoft.Extensions.Logging.ILogger<>))); services.AddSingleton<ILoggerProvider>(_ => new SerilogLoggerProvider(Log.Logger, true)); services.AddLogging(configure => configure.AddSerilog(Log.Logger)); Autofac.ContainerBuilder containerBuilder = new(); containerBuilder.Populate(services); ConfigureContainer(containerBuilder, configurationRoot); }) .Build(); await host .RunAsync() .ConfigureAwait(false);
控制台输出异常
日志输出出现以下问题:
- [2023-01-18T16:15:38.238Z] Azure Functions .NET Worker (PID: 9984) initialized in debug mode. Waiting for debugger to attach...
- [2023-01-18T16:15:42.934Z] Host lock lease acquired by instance ID '000000000000000000000000A74958CE'.
- [2023-01-18T16:15:44.781Z] [2023-01-18T17:15:44.6592148 +01:00|DBG] [] [Microsoft.Extensions.Hosting.Internal.Host.MoveNext()] Hosting starting
- [2023-01-18T16:15:44.786Z] [2023-01-18T17:15:44.7769259 +01:00|DBG] [] [Microsoft.Extensions.Hosting.Internal.Host.MoveNext()] Hosting starting
- [2023-01-18T16:15:46.919Z] [2023-01-18T17:15:46.9065003 +01:00|INF] [] [Microsoft.Extensions.Hosting.Internal.ConsoleLifetime.OnApplicationStarted()] Application started. Press Ctrl+C to shut down.
- [2023-01-18T16:15:46.926Z] [2023-01-18T17:15:46.9184378 +01:00|INF] [] [Microsoft.Extensions.Hosting.Internal.ConsoleLifetime.OnApplicationStarted()] Application started. Press Ctrl+C to shut down.
核心问题
- 从第三行开始,日期出现重复(日志模板仅定义了一个日期)
- 日志条目重复输出
解决方案
1. 问题根源
- 日志重复:代码中手动注册了两次Serilog日志提供器(
AddSingleton<ILoggerProvider>和AddLogging(configure => configure.AddSerilog)),导致每条日志被两次处理输出;同时手动移除ILoggerFactory和ILogger<>破坏了Azure Functions Host默认的日志基础设施,引发冲突。 - 日期重复:Azure Functions Worker会自动在控制台日志前附加UTC时间戳,而Serilog的输出模板中又包含了另一个日期格式,两者叠加导致重复。
2. 修正后的代码
Log.Logger = LoggerConfigurationFactory .GetLoggerConfiguration(LogEventLevel.Debug) .CreateLogger(); IConfigurationRoot configurationRoot = GetConfiguration(); IHost host = new HostBuilder() .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureFunctionsWorkerDefaults() // 使用Serilog官方推荐的Host集成方式,自动处理日志提供器注册 .UseSerilog((context, loggerConfig) => { // 复用预先配置的Logger,或在此处补充配置 loggerConfig.ReadFrom.Configuration(context.Configuration); loggerConfig.MinimumLevel.Debug(); }, preserveStaticLogger: true) .ConfigureServices(services => { // 移除手动修改LoggerFactory的代码 Autofac.ContainerBuilder containerBuilder = new(); containerBuilder.Populate(services); ConfigureContainer(containerBuilder, configurationRoot); }) .Build(); await host.RunAsync().ConfigureAwait(false);
3. 调整Serilog输出模板解决日期重复
修改LoggerConfigurationFactory中的控制台输出配置,移除模板内的日期字段,让Azure Functions Host统一处理日志前缀:
public static LoggerConfiguration GetLoggerConfiguration(LogEventLevel level) { return new LoggerConfiguration() .MinimumLevel.Is(level) // 输出模板去掉日期,由Host统一添加前缀日期 .WriteTo.Console(outputTemplate: "{Level:u3} | {Message:lj} {Properties:j}{NewLine}{Exception}"); }
4. 关键说明
UseSerilog是Serilog官方推荐的与.NET Host集成的方式,会自动避免重复注册日志提供器,同时兼容Azure Functions的日志系统。preserveStaticLogger: true参数保留预先创建的Log.Logger实例,无需重新构建配置。- 不要手动移除
ILoggerFactory或ILogger<>,Azure Functions Host依赖这些类型维护日志管道,强行移除会导致不可预知的冲突。
内容的提问来源于stack exchange,提问作者Attilio Gelosa
相关产品推荐
相关产品推荐

