2017-08-08 58 views
1

我现在正在使用ASP.NET核心LoggerFactorySerilog扩展)使用记录工作。我想把日志放在控制器和业务服务方法中。我这样做,是通过构造函数注入的​​这样ASP.NET核心 - 记录器的多个实例

在控制器:

ILogger<HomeController> _logger 

在服务:

ILogger<ServiceName> _logger 

我相信,这将在每个请求被实例化,所以对于每个HTTP请求它会创建Logger的多个实例。说每个控制器和每个服务类,但它与以前的记录方法有点不同,我们只用于创建一个记录器实例,并用它来记录任何地方的东西。

这有什么缺点?

回答

2

这完全没问题。通常,实例化记录器很便宜,因此完全可以像执行性能那样进行。

仍然可以考虑(1)使用Serilog所具有的全局日志实例,或者(2)使用在字段声明中初始化的静态字段。再一次,不是出于性能的原因,而是为了避免污染你的构造函数而不是相关的东西。

UPD更新关于实施(1)

基本上,它只是一个决定会在哪里你把记录器初始化代码到的问题。在ASP.NET核心将是Main方法的第一行(即LogSerilog命名空间的静态类):

Log.Logger = new LoggerConfiguration().WriteTo.LiterateConsole(LogEventLevel.Debug, LogTemplate) 
               .WriteTo.File(@"C:\logs\elbakogdabot.log", LogEventLevel.Debug, LogTemplate) 
               .Enrich.FromLogContext() 
               .CreateLogger(); 

(仅仅是明确的:我把代码从我的实际项目,但是记录器的实际配置可能不同)。

然后我会在任何地方使用它像这样:

Log.Warning($"got a message for an unknown user: userid=[{userId}]"); 

此行可能被扔进任何类,你不必做任何额外的初始化这个类。

UPD更新关于执行(2)

我想在一个典型的企业应用程序这将是有问题永远记得你每次登录的东西的时候把类名在邮件中。所以我大部分时间都会去static readonly。随着Serilog你可以做这样的:

public class XYZService 
{ 
    private static readonly Serilog.ILogger log = Log.ForContext<XYZService>(); 
... 

这样你既不会污染构造,并会自动在您所有的日志信息的获取类名。我曾经在ReSharper片段中有这条线,所以我不得不在每个新班级中输入lg<TAB>

+0

感谢您的快速回复。选项1的任何好的参考文章? – vibs

+0

听起来不错。我试图在我的代码中实现它。它的工作原理! – vibs

+0

只有两件事:1)我必须在我的业务库中安装serilog nuget软件包以获取Log对象的访问权限2)我的输出模板格式没有获取sourcecontext,因为它是全局的。所以我们必须在日志消息中编写n类方法的详细信息。如果错了,纠正我。 – vibs