Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET核心-记录器的多个实例_C#_Logging_Asp.net Core - Fatal编程技术网

C# ASP.NET核心-记录器的多个实例

C# ASP.NET核心-记录器的多个实例,c#,logging,asp.net-core,C#,Logging,Asp.net Core,我现在正在使用ASP.NET CoreLoggerFactory(扩展名)进行日志记录。我想将日志放入控制器和业务服务方法中。我已经通过像这样的ILogger的构造函数注入做到了这一点 在控制器中: ILogger<HomeController> _logger ILogger\u记录器 在职: ILogger<ServiceName> _logger ILogger\u记录器 我相信这将在每个请求中实例化,因此对于每个HTTP请求,它将创建多个Logger实例。

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

在控制器中:

ILogger<HomeController> _logger
ILogger\u记录器
在职:

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


这有什么坏处吗

这完全没问题。通常,实例化一个日志程序是很便宜的,所以从性能角度来看,完全可以这样做

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

UPD实施更新(1)

基本上,这只是决定将logger init代码放入何处的问题。在ASP.NET核心中,它将是
Main
方法的第一行(即
Log
Serilog
命名空间中的一个静态类):

(我只是想澄清一下:我从我的一个真实项目中获取了代码,但是您的记录器的实际配置可能会有所不同)

然后我会在任何地方使用它,就像这样:

Log.Warning($"got a message for an unknown user: userid=[{userId}]");
这一行可以抛出到任何类中,您不必对该类进行任何额外的初始化

UPD实施更新(2)

我猜在一个典型的企业应用程序中,每次登录某个内容时,总是记住在消息中输入类名是不方便的。所以我大部分时间都使用
静态只读
字段。使用Serilog,您可以这样做:

public class XYZService
{
  private static readonly Serilog.ILogger log = Log.ForContext<XYZService>();
...
公共类XYZ服务
{
私有静态只读Serilog.ILogger log=log.ForContext();
...

这样,你们两个都不会污染构造函数,并且会自动在所有日志消息中获取类名。我以前在ReSharper代码段中有这一行,所以我必须在每个新类中键入
lg

感谢您的快速回复。有没有关于选项1的好参考文章?听起来不错。我尝试在代码中实现这一点。而且它是有效的!只有两件事:1)我必须在我的业务库中安装serilog nuget软件包才能访问日志对象2)我没有以输出模板格式获取sourcecontext,因为它是全局的。因此我们必须在日志消息中写入类n方法详细信息。如果错误,请更正我。(1)是的,你必须这样做,但这通常不是什么大问题。它不会让你的“业务库”变得不干净或什么的。如果你必须避免这种情况,我想你可以在它周围实现你自己的包装器,但你仍然需要引用它位于(2)中的程序集是的,您必须自己写;好的,即使您使用构造函数注入方法,您仍然必须手动将方法名放在日志消息中,这只是自动写入的类名;如果我错了,请纠正我不客气;此外,为了完整性,请用(2)的示例更新答案
public class XYZService
{
  private static readonly Serilog.ILogger log = Log.ForContext<XYZService>();
...