.NET6中Serilog配置appsettings.json时SourceContext不生效问题
问题描述
在.NET6应用中使用Serilog结合appsettings.json配置,期望日志中显示SourceContext字段,但测试代码未返回预期结果,需明确正确的配置与使用方式。
当前配置与代码
NuGet包引用
<PackageReference Include="Serilog" Version="2.11.0" /> <PackageReference Include="Serilog.AspNetCore" Version="6.0.1" /> <PackageReference Include="Serilog.Enrichers.CorrelationId" Version="3.0.1" /> <PackageReference Include="Serilog.Enrichers.Environment" Version="2.2.0" /> <PackageReference Include="Serilog.Enrichers.Process" Version="2.0.2" /> <PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" /> <PackageReference Include="Serilog.Expressions" Version="3.4.0" /> <PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" /> <PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
Program.cs(原代码)
IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .CreateLogger();
appsettings.json配置
"Serilog": { "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ], "MinimumLevel": { "Default": "Verbose" }, "Enrich": [ "WithOpenTracingContext", "FromLogContext", "WithMachineName", "WithEnvironmentUserName", "WithProcessId", "WithThreadId" ], "WriteTo": [ { "Name": "Console", "Args": { "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [SourceContext: {SourceContext}] {Message}{NewLine}{Exception}" } } ], "Properties": { "Application": "app name" } }
关键问题与修复步骤
1. 必须使用ILogger而非静态Log.Logger
SourceContext是Serilog为**泛型ILoggerLog.Logger静态方法不会自动添加该属性,除非手动通过LogContext.PushProperty设置。
2. 正确将Serilog注册到.NET日志系统
原代码仅初始化了Serilog的静态Logger,但未将其集成到.NET依赖注入的日志系统中,导致ILogger
对于Web应用(.NET6顶级语句):
var builder = WebApplication.CreateBuilder(args); // 配置Serilog并注册为日志提供者 builder.Host.UseSerilog((context, loggerConfig) => loggerConfig.ReadFrom.Configuration(context.Configuration)); // 注册其他服务... var app = builder.Build(); // 配置中间件... app.Run();
对于控制台应用:
var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .CreateLogger(); // 注册Serilog到依赖注入的日志系统 using var serviceProvider = new ServiceCollection() .AddLogging(loggingBuilder => loggingBuilder.AddSerilog()) .BuildServiceProvider(); // 获取泛型Logger var logger = serviceProvider.GetRequiredService<ILogger<Program>>(); logger.LogInformation("这是一条测试日志,SourceContext会自动填充为Program类的完整类型名");
3. 验证Enrich配置
你的Enrich中已包含FromLogContext,该配置正确——它支持手动通过LogContext.PushProperty添加自定义上下文属性,但使用ILogger
4. 确认输出模板
你的输出模板{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [SourceContext: {SourceContext}] {Message}{NewLine}{Exception}格式正确,当SourceContext存在时,会显示类似[SourceContext: YourAppNamespace.Program]的内容。
测试验证
修改代码后运行应用,日志输出应包含对应的SourceContext值。若仍未显示,可检查:
- 未手动覆盖SourceContext属性
- NuGet包版本兼容(Serilog.AspNetCore 6.0.1与.NET6匹配)
- 日志语句级别不低于配置的MinimumLevel(当前为Verbose)
内容的提问来源于stack exchange,提问作者Leandro Quinteros

