【问题标题】:Serilog DI in ASP.NET Core, which ILogger interface to inject?ASP.NET Core 中的 Serilog DI,要注入哪个 ILogger 接口?
【发布时间】:2020-08-08 05:26:19
【问题描述】:

上下文

我已经在我的 ASP.NET Core 应用程序中成功配置了 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 一起使用的解决方案是什么?

【问题讨论】:

    标签: asp.net-core dependency-injection serilog


    【解决方案1】:

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

    您可能有兴趣在 Serilog 的 repo 上阅读此问题:

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

    我个人在所有项目中都使用 Serilog 的 ILogger,不仅因为我更喜欢较短的方法名称,还因为我更喜欢 在每个类的每个构造函数中注入记录器,使用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>();
        // ...
    }
    

    如果您正在开发库,我当然建议您使用 Microsoft 的通用 ILogger&lt;&gt;,而不是依赖于 Serilog 并强制您的库的使用者也使用对Serilog 的依赖。


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

    【讨论】:

    • 谢谢,但是单元测试呢?硬编码 Log.ForContext 要求单元测试必须处理真正的 Serilog 记录器而不是模拟,并使用例如模拟来断言日志记录功能。
    • @g.pickardou 不是真的... 它只是工作 (tm)... 默认情况下,Log.Logger 指向一个 SilentLogger,它执行一个 @987654324 @ 所以你不必为你的单元测试做任何特别的事情......
    • @g.pickardou 当然,如果你想测试特定的日志输出,那么你只需要创建一个 Serilog 的 ILogger 的模拟实现并将Log.Logger 更改为指向模拟,在你的测试中......
    【解决方案2】:

    您应该按照文档 (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&lt;&gt;。这个ILogger&lt;&gt; 实例将自动记录到所有您已配置的提供程序(这可能包括 Serilog,但也包括配置的任何其他记录器,例如文件、控制台等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 2021-12-17
      • 2015-03-07
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      相关资源
      最近更新 更多