首页 > 解决方案 > 使用 Serilog 的模式(通过 ILogger 与使用静态 Serilog.Log)

问题描述

背景

在一个选择Serilog作为记录器的新项目中,我自动开始传递ILogger接口。代码访问Log.Logger一次,然后ILogger通过构造函数注入接受需要记录的类。

我在这种做法上受到了挑战,建议是在Log课堂上使用静态方法,例如Serilog.Log.Debug(...). 争论是有一个set;onLog.Logger所以嘲笑很容易。

查看 api 我可以看到传递的好处之一ILoggerForContext方法。

我在网上和Serilog的文档中花了一些时间,但我找不到有关在整个应用程序代码中访问日志的规范方法的信息。

问题

是否有一种规范的,即在大多数情况下更好的方式来访问/传递Serilog记录器,如果有,它是传递ILogger还是使用Serilog.Log类上的静态 api?

标签: c#serilog

解决方案


还有一个ForContexton Log.Logger,所以我不会在此基础上决定。如果您正在模拟/测试日志记录,您不希望通过单个全局实例来执行此操作。相反,任何将进行日志记录的库代码都应该接受一个ILogger参数作为输入,使调用者能够检测和/或只是在Log.Logger他们认为合适的时候传入(不要在Log.Logger内部添加默认值,原因与具有默认构造函数的原因相同)自动构建您想要从中解耦的依赖项是一个坏主意)。如果您不这样做,您将无法有意义地测试日志输出是否正确(因为最终并行运行的任何并发测试都将写入完全相同的记录器实例),这是一件大事向上。

对我来说,主要的权衡实际上是您是否愿意使用Enrich.FromLogContext以及将LogContext.*状态挂在 .NET 上的接口,ExecutionContext您需要小心不要发疯。(是的,可以说你可以使用一个被隔离的收集器ExecutionContext来破解我之前的观点,但甚至不要去那里。)

根据您的 DI 的装配方式,您可能想要ILogger<T>输入您的输入,但同样,除非有人需要能够通过仪器获取信息,static ILogger _logger = Log.ForContext<MyClass>()只要Log足够早地连接起来就可以了。


推荐阅读