Serilog DI in ASP.NET Core,注入哪个ILogger接口?

Serilog DI in ASP.NET Core, which ILogger interface to inject?

上下文

我已经在我的 ASP.NET 核心应用程序中成功配置了 Serilog,只剩下 DI 部分。

问题

现在我有两个ILogger 接口,一个是Serilog.ILogger,另一个是Microsoft.Extensions.Logging.ILogger。两者都基于我的 Serilog 配置,但我不知道该使用哪个? (我的意思是,在 Serilog 配置到位后 Microsoft.Extensions.Logging.ILogger 也可以通过 Serilog 正确登录,所以我的配置是有效的)

如果 Microsoft.Extensions.Logging.ILogger 我知道如何配置 DI 使其工作。 但是,在 Serilog.ILogger 的情况下,我看到 Serilog 有一个静态 Log.Logger 实例(可能是单例)

我不想在我的代码中使用这个静态 属性,主要是出于测试原因,所以我想在构造函数中注入它。解决方案是:

services.AddSingleton(Log.Logger); // Log.Logger is a singleton anyway

..但是当许多多个线程同时使用同一个实例时,我担心 Web 应用程序中的这个单例。它是线程安全的吗?如果不是,那么将 Serilog.ILogger 与 DI 一起使用的解决方案是什么?

您应该按照文档 (https://github.com/serilog/serilog/wiki/Getting-Started) 中的描述,将 Program.cs 文件中的日志记录设置为 Host 设置的一部分。

如上所示,您不应手动向 ServiceCollection 添加任何内容。

对于 DI,您应该按照文档 (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/#create-logs) 中的描述注入 Microsoft 通用 ILogger<>。此 ILogger<> 实例将自动记录到 所有 您配置的提供程序(这可能包括 Serilog,但也包括配置的任何其他记录器,例如文件、控制台等)。

选择在您的应用程序中使用哪个界面是一个品味问题,真的。如果您更喜欢 Serilog 的 ILogger 更短的方法名称(例如 log.Errorlog.LogError),请使用它,否则使用 Microsoft 的通用 ILogger<>。您可以控制在自己的项目中使用的所有依赖项,因此没有充分的技术理由偏爱其中一个。

你可能有兴趣在 Serilog 的 repo 上阅读这个问题:

Should I use Microsoft.Extensions.Logging.ILogger or Serilog.ILogger?.

我个人在我的所有项目中都使用 Serilog 的 ILogger,不仅因为我确实更喜欢较短的方法名称,而且因为我更喜欢 而不是 来注入记录器每个 class 的每个构造函数,使用 Log.ForContext<> 也很容易得到 contextual logger for every class,这在解决问题时很有用。例如

public class SomeService
{
    private readonly ILogger _log = Log.ForContext<SomeService>();
    // ...
}

public class SomeRepository
{
    private readonly ILogger _log = Log.ForContext<SomeRepository>();
    // ...
}

如果你正在开发一个库,我当然建议使用微软的通用 ILogger<>,而不是依赖 Serilog并强制您的图书馆的消费者也依赖 Serilog.


Log.Logger 是线程安全的,因此如果您希望所有 classes 共享同一个实例 (without SourceContexts),那么像上面那样注册为单例是正确的 -没有错。