如何按SourceContext拆分Serilog日志文件?求可行解决方案
解决Serilog按SourceContext拆分日志的配置问题
我尝试按SourceContext拆分Serilog日志,花费数天查阅文档及大量帖子后,配置了如下Serilog配置但未解决问题:
"Serilog": { "Using": [ "Serilog.Sinks.Debug", "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Expressions" ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft.AspNetCore": "Information", "Microsoft": "Warning", "System": "Warning" } }, "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}" } }, { "Name": "Logger", "Args": { "confgureLogger": { "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-HTTP-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} {Namespace} - {Message:lj}{NewLine}{Exception}" } } ], "Filter": [ { "Name": "ByIncludingOnly", "Args": { "expression": "StartsWith(SourceContext, 'Microsoft.AspNetCore')" } } ] } } }, { "Name": "Logger", "Args": { "confgureLogger": { "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-API-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} {Namespace} - {Message:lj}{NewLine}{Exception}" } } ], "Filter": [ { "Name": "ByIncludingOnly", "Args": { "expression": "StartsWith(SourceContext, 'My.Application')" } } ] } } }, { "Name": "Console", "Args": { "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} {NameSpace} - {Message:lj}{NewLine}{Exception}" } } ] }
我尝试过使用subLogs和多根日志配置:使用subLogs时仅生成一个日志文件;使用多根日志时,同一日志会重复出现在多个文件中。目前我除了考虑更换日志框架为NLog外,不知道该如何解决,请问是否有可行的解决方案?
核心问题与修正方案
你的配置里存在一个致命拼写错误:confgureLogger应为configureLogger(缺少字母i),这直接导致嵌套的子Logger未被正确初始化,所以不会生成对应的拆分日志文件。
修正后的完整配置如下:
"Serilog": { "Using": [ "Serilog.Sinks.Debug", "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Expressions" ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft.AspNetCore": "Information", "Microsoft": "Warning", "System": "Warning" } }, "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-all-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}", // 可选:如果不想主日志包含已拆分内容,添加过滤规则 "filter": "!(StartsWith(SourceContext, 'Microsoft.AspNetCore') || StartsWith(SourceContext, 'My.Application'))" } }, { "Name": "Logger", "Args": { "configureLogger": { "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-HTTP-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}" } } ], "Filter": [ { "Name": "ByIncludingOnly", "Args": { "expression": "StartsWith(SourceContext, 'Microsoft.AspNetCore')" } } ] } } }, { "Name": "Logger", "Args": { "configureLogger": { "WriteTo": [ { "Name": "File", "Args": { "path": "Logs/log-API-.txt", "rollingInterval": "Day", "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}" } } ], "Filter": [ { "Name": "ByIncludingOnly", "Args": { "expression": "StartsWith(SourceContext, 'My.Application')" } } ] } } }, { "Name": "Console", "Args": { "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {SourceContext} - {Message:lj}{NewLine}{Exception}" } } ] }
额外注意事项
- 移除无效的
Namespace属性:Serilog默认不会生成Namespace日志属性,输出模板中的{Namespace}会显示为空,建议直接移除该字段。 - 避免日志重复:如果主日志文件(
log-all-.txt)不需要包含已拆分到log-HTTP-.txt和log-API-.txt的内容,添加filter参数过滤对应的SourceContext即可。 - 确认包依赖:确保已正确安装
Serilog.Expressions包,因为你使用了StartsWith表达式过滤规则。 - 多根日志重复问题:之前使用多根日志时出现重复,是因为每个根日志会独立处理所有日志事件;而上述嵌套Logger的方式是在主日志管道内分流,不会重复触发主日志的写入逻辑。
内容的提问来源于stack exchange,提问作者Glauco Cucchiar
相关产品推荐
相关产品推荐

