ASP.NET Core - Logger的多个实例

时间:2017-08-08 02:28:49

标签: c# logging asp.net-core

我现在正在使用ASP.NET Core LoggerFactorySerilog扩展名)进行日志记录。我想将日志放在控制器和业务服务方法中。我已经通过构造函数注入ILogger这样做了

在控制器中:

ILogger<HomeController> _logger

在服务中:

ILogger<ServiceName> _logger

我相信这将在每个请求中实例化,因此对于每个HTTP请求,它将创建多个Logger实例。比如每个控制器和每个服务类,但它与以前的日志记录方法有点不同,我们以前只创建一个记录器实例,并用它来记录任何地方的内容。

有什么缺点吗?

1 个答案:

答案 0 :(得分:3)

这完全没问题。通常情况下,实例化记录器很便宜,所以完全可以像表现那样做。

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

UPD 有关实施(1)的更新

基本上,只需确定将记录器初始化代码放入何处即可。在ASP.NET Core中,它将是Main方法的第一行(Log是来自Serilog命名空间的静态类):

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>