我的 .Net Core 应用程序中可以有两种不同类型的 ILogger 吗?
Posted
技术标签:
【中文标题】我的 .Net Core 应用程序中可以有两种不同类型的 ILogger 吗?【英文标题】:Can I have two different kinds of ILoggers in my .Net Core application? 【发布时间】:2021-09-06 15:51:11 【问题描述】:我的应用程序有一部分只想登录到 EventLog。其余时间,我想登录到为我的ILogger
s 设置的所有正常事件接收器。
我可以通过这样做在这些部分制作 ILogger:
var eventLogLoggerProvider = new Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider();
var eventLogger = eventLogLoggerProvider.CreateLogger("EventLogger");
eventLogger.LogWarning("We logged to the event log!");
但我觉得我应该通过依赖注入来做到这一点。但所有示例都只是显示为整个应用程序设置一次。
有没有办法将 ASP.Net Core 3.1 应用程序配置为具有两种不同类型的 ILogger?(并允许将其中一种注入到一个类中?)
【问题讨论】:
您的意思是像“将跟踪级别记录到控制台,将警告级别记录到 EventLog 并将错误级别记录到某些外部服务,这些服务会 ping 技术团队的手机”?可以使用为不同级别配置的一个记录器来完成.. 任何你可以用 new 做的事情,你可以用 DI 做,如果你可以教容器知道区别(比如有两个实现 ilogger 的类) - DI 不是魔法,它只是看着构造函数签名,然后“哦。这个构造函数想要一个 ConsoleLogger 而不是 ILogger,我已经注册了其中一个,给你”,在其他一些场景中发送一些其他注册的 impl;只需制作另一种类型的记录器并以 DI 可以判断使用哪个以及何时使用的方式注册它 在启动时检查环境并相应地注册不同的记录器会更简单吗? 【参考方案1】:有多种选择供您选择。但是,它们都不会特别好。 .NET Extensions DI 有点简单,而您的方案似乎相当先进。
直接使用EventLog
如果您如此拘泥于在应用程序的特定位置使用 EventLog,那么直接使用它可能是有意义的,因为 ILogger 抽象基本上与您的要求相反。
有了ILogger
依赖,你说的是“给我一个记录器,不管它是什么,我不在乎”。但你确实在乎。那么为什么不直接使用EventLog呢?或者可能将其隐藏在接口和适配器后面以实现可测试性并将其注入。
日志配置
另外,如果您通过 appsettings.json 配置日志记录,则您会遇到更少的摩擦,以便 EventLog 具有默认的 LogLevel = None 和 LogLevel = Information 或任何您喜欢的事件记录程序集/命名空间。并且其余记录器对于事件记录区域具有 None LogLevel。例如:
"Logging":
"LogLevel":
"Default": "Information",
"My.EventLogged.Assembly": "None"
,
"EventLog":
"Default": "None",
"My.EventLogged.Assembly": "Information"
如果您将代码隔离到一个程序集或几个命名空间中,这会很好地工作,但很容易添加另一个您只需要事件日志的地方而忘记对其进行配置。
有关详细信息,请参阅 Logging in .NET Core and ASP.NET Core, Configuration section.
提供额外的上下文
如果您只需要事件日志记录的区域很容易分离,您可以提供一个具有单例生命周期的外观,它将创建一个单独的 IServiceCollection/IServicePrivoder,其中事件日志是该容器中唯一注册的 ILogger。
对事件记录代码的任何调用都应通过外观,该外观将使用内部 IServiceProvider 调用预期的实现。如果您需要从事件记录代码调用应用程序的其余部分,则需要执行相反的操作。
这并不简单,但即使 ASP.NET Core 本身也这样做(或至少这样做)是为了在服务初始化尚未完成时在启动期间提供日志记录。
但它肯定有令人惊讶的元素,并且可能会导致调试和诊断服务设置时有些头疼。设置中也会有重复。我确实认为这不是一个值得的方法。
使用不同的 IoC 容器
autofac 或 castle 等其他容器可能能够基于使用名称的实例标识来解析多个服务(在本例中为 ILogger)。参见例如AutoFac FAQ: How do I pick service implementation by context.
但是,我无法建议如何使用 ILogger 来执行此操作,因为日志记录注册相当复杂。
这些只是我能想到的一些方向。对于您的要求,我认为没有简单、规范的答案,您必须根据您的具体需求和情况进一步研究这些选项。
【讨论】:
在日志配置中可以指定一个过滤器,它只会在发送特定类别的消息时导致事件日志记录器记录。我认为这最接近预期结果以上是关于我的 .Net Core 应用程序中可以有两种不同类型的 ILogger 吗?的主要内容,如果未能解决你的问题,请参考以下文章
启动时在 Linux 下运行 ASP.NET Core 应用程序