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.Error
与 log.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 SourceContext
s),那么像上面那样注册为单例是正确的 -没有错。
上下文
我已经在我的 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.Error
与 log.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 SourceContext
s),那么像上面那样注册为单例是正确的 -没有错。