.NET Core Worker Service同时配置Serilog与SQL日志提供器失效问题
解决.NET Core Worker Service同时配置Serilog与自定义SQL Server日志提供器仅Serilog生效的问题
问题原因
调用builder.Services.AddSerilog()时,默认会用SerilogLoggerFactory替换.NET原生的LoggerFactory,而之前通过AddLogging.AddProvider注册的自定义SQL Server日志提供器绑定在原生LoggerFactory上,替换后就无法生效了。
解决方案
方案1:将自定义SQL Server提供器转为Serilog Sink
把自定义SQL Server日志逻辑改造成Serilog的Sink,让Serilog直接输出日志到SQL Server,同时保留文件和控制台输出。
- 实现Serilog的
ILogEventSink接口:
public class SqlServerSerilogSink : ILogEventSink { private readonly string _connectionString; private readonly LogEventLevel _minimumLevel; public SqlServerSerilogSink(string connectionString, LogEventLevel minimumLevel) { _connectionString = connectionString; _minimumLevel = minimumLevel; } public void Emit(LogEvent logEvent) { if (logEvent.Level < _minimumLevel) return; // 复用原SqlServerLoggerProvider中的日志写入逻辑 // 例如将logEvent转换为数据库实体并插入SQL Server } }
- 修改Serilog配置,添加这个Sink:
var logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "logs", "workerService-{Date}.txt"); builder.Services.AddSerilog(loggingBuilder => loggingBuilder.MinimumLevel.Debug() .WriteTo.Console() .WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10 * 1024 * 1024) .WriteTo.Sink(new SqlServerSerilogSink(connectionString.Value, sqlServerMinimumLogLevel)));
方案2:让Serilog转发日志到原有日志提供器
如果不想修改现有自定义提供器,可借助Serilog.Sinks.Providers包将日志转发到已注册的所有日志提供器。
- 安装NuGet包:
Install-Package Serilog.Sinks.Providers
- 调整配置代码顺序与逻辑:
// 先注册自定义SQL Server日志提供器 builder.Services.AddLogging(configure => { configure.AddProvider(new SqlServerLoggerProvider(connectionString.Value, sqlServerMinimumLogLevel)); }); var logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "logs", "workerService-{Date}.txt"); // 使用Host.UseSerilog配置,注入ILoggerFactory并转发日志 builder.Host.UseSerilog((context, services, loggerConfig) => { loggerConfig .MinimumLevel.Debug() .WriteTo.Console() .WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10 * 1024 * 1024) // 将日志转发到所有已注册的ILoggerProvider .WriteTo.Providers(services.GetRequiredService<ILoggerFactory>()); });
内容的提问来源于stack exchange,提问作者user3497702
相关产品推荐
相关产品推荐

