NLog "final" 规则的 Serilog 替代方案
Alternative in Serilog for NLog's "final" rule
可以这样配置 NLog:
<rules>
<logger name="Microsoft.EntityFrameworkCore.*" minlevel="Trace" writeTo="file-ef" final="true" />
<logger name="Microsoft.*" minlevel="Trace" writeTo="file-http,console" final="true" />
<logger name="*" minlevel="Trace" writeTo="file,console" />
</rules>
rules 的 final
关键字可以为以下对象使用单独的目标:
Microsoft.EntityFrameworkCore.*
记录器
- 其他
Microsoft.*
个记录器
- 所有其他记录器
配置简单明了,我可以轻松添加另一个条件,而无需修改所有其他规则。
用 Serilog 做同样的事情我必须写下面的代码:
const string format = "[{Timestamp:HH:mm:ss.fff} {ThreadId} {Level:u3}] {Message:lj} [{SourceContext}] {NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.WriteTo.Console(outputTemplate: format)
.WriteTo.Logger(cfg => cfg
.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.AspNetCore"))
.WriteTo.RollingFile(@"logs\{Date}.http.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.WriteTo.Logger(cfg => cfg
.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore"))
.WriteTo.RollingFile(@"logs\{Date}.ef.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.WriteTo.Logger(cfg => cfg.Filter
.ByExcluding(Matching.FromSource("Microsoft"))
.WriteTo.RollingFile(@"logs\{Date}.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.CreateLogger();
要添加另一个条件,我必须将其从所有其他过滤器中排除。
问题:我是不是遗漏了什么,或者如果有匹配的规则,没有简单的方法可以跳过其他规则?
这不是 Serilog 的 API 特别强大的场景,
但 Serilog.Sinks.Map 涵盖了这种情况。
// Install-Package Serilog.Sinks.Map -Pre
var isAsp = Matching.FromSource("Microsoft.AspNetCore");
var isEF = Matching.FromSource("Microsoft.EntityFrameworkCore");
var isMS = Matching.FromSource("Microsoft");
Log.Logger = new LoggerConfiguration()
.WriteTo.Map(le => isAsp(le) ? ".http" :
isEF(le) ? ".ef" :
!isMS(le) ? ".other" :
"",
(slug, wt) => wt.RollingFile($"logs\{{Date}}{slug}.log"))
.CreateLogger();
可以这样配置 NLog:
<rules>
<logger name="Microsoft.EntityFrameworkCore.*" minlevel="Trace" writeTo="file-ef" final="true" />
<logger name="Microsoft.*" minlevel="Trace" writeTo="file-http,console" final="true" />
<logger name="*" minlevel="Trace" writeTo="file,console" />
</rules>
rules 的 final
关键字可以为以下对象使用单独的目标:
Microsoft.EntityFrameworkCore.*
记录器- 其他
Microsoft.*
个记录器 - 所有其他记录器
配置简单明了,我可以轻松添加另一个条件,而无需修改所有其他规则。
用 Serilog 做同样的事情我必须写下面的代码:
const string format = "[{Timestamp:HH:mm:ss.fff} {ThreadId} {Level:u3}] {Message:lj} [{SourceContext}] {NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.WriteTo.Console(outputTemplate: format)
.WriteTo.Logger(cfg => cfg
.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.AspNetCore"))
.WriteTo.RollingFile(@"logs\{Date}.http.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.WriteTo.Logger(cfg => cfg
.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore"))
.WriteTo.RollingFile(@"logs\{Date}.ef.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.WriteTo.Logger(cfg => cfg.Filter
.ByExcluding(Matching.FromSource("Microsoft"))
.WriteTo.RollingFile(@"logs\{Date}.log", outputTemplate: format, retainedFileCountLimit: null, buffered: true))
.CreateLogger();
要添加另一个条件,我必须将其从所有其他过滤器中排除。
问题:我是不是遗漏了什么,或者如果有匹配的规则,没有简单的方法可以跳过其他规则?
这不是 Serilog 的 API 特别强大的场景, 但 Serilog.Sinks.Map 涵盖了这种情况。
// Install-Package Serilog.Sinks.Map -Pre
var isAsp = Matching.FromSource("Microsoft.AspNetCore");
var isEF = Matching.FromSource("Microsoft.EntityFrameworkCore");
var isMS = Matching.FromSource("Microsoft");
Log.Logger = new LoggerConfiguration()
.WriteTo.Map(le => isAsp(le) ? ".http" :
isEF(le) ? ".ef" :
!isMS(le) ? ".other" :
"",
(slug, wt) => wt.RollingFile($"logs\{{Date}}{slug}.log"))
.CreateLogger();