我知道可以使用MinimumLevel.Override,然后为每个namespace或type定义特定的日志记录级别,但是如果我想通过更特定于我的上下文或要求的内容来记录它怎么办?
例如,在我的应用程序中,我希望为与用户实体相关的任何内容拥有一个特定的日志记录组。不过,这并不绑定到特定的命名空间或类,它可以是控制器、存储库或任何自定义服务中的代码。在调试与用户相关的内容时,我想为其打开详细日志记录,但不要为任何其他日志、服务或控制器增加详细日志记录,即使它们与用户共享命名空间。 再说一遍,“用户”只是一个例子 - 它可能与我正在执行的特定类型的 SQL 查询相关,每当使用某些服务时,只有当某些代码深处的特定条件运行时,等等 - 也许我想要所有SQL 查询仅在错误时记录,除了少数应该是详细的。
我第一次尝试用开关来做到这一点
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.MinimumLevel.Override("Case1", SerilogSwitches.Case1)
.MinimumLevel.Override("Case2", SerilogSwitches.Case2)
.CreateLogger();
问题是“Case1”和“Case2”必须匹配某些特定的命名空间或类型,这对我来说不够好。
我还研究了使用 Log.ForContext 为每种情况创建特定的记录器上下文
var logger1 = Log.ForContext("Context", "Case1");
var logger2 = Log.ForContext("Context", "Case2");
虽然这可以让我在任何时候选择要使用的记录器,然后更轻松地查找和过滤特定上下文的日志,但它们仍然以相同的级别记录 - 我不认为我可以更改日志记录级别特定上下文,例如 Case1 位于信息处,而 Case2 位于错误处。
如有任何帮助,我们将不胜感激
您可以尝试使用
WriteTo.Conditional
根据“Context”值确定配置。比如下面的例子:
Log.Logger = new LoggerConfiguration()
.WriteTo.Conditional((evt) => {
var contextValue = ((ScalarValue)evt.Properties.GetValueOrDefault("Context")).Value;
return ( contextValue== "case1");
} , wt => wt.Console(restrictedToMinimumLevel:LogEventLevel.Information,outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}]({Context}) {Message:lj}{NewLine}{Exception}"))
.WriteTo.Conditional((evt) => {
var contextValue = ((ScalarValue)evt.Properties.GetValueOrDefault("Context")).Value;
return (contextValue == "case2");
}, wt => wt.Console(restrictedToMinimumLevel: LogEventLevel.Error, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}]({Context}) {Message:lj}{NewLine}{Exception}"))
.CreateLogger();
测试
Log.ForContext("Context","case1").Information("case1 info");
Log.ForContext("Context", "case2").Information("case2 info");
Log.ForContext("Context", "case2").Error("case2 error");