Serilog JSON配置中的“使用”有什么作用?

时间:2018-12-15 18:39:11

标签: c# .net-core serilog

Using在Serilog JSON配置中(例如,.Net Core环境中的AppSettings.json文件)实际上是做什么的?

让我们以以下配置为例:

"Serilog": {
  "Using": [ "Serilog.Sinks.Console" ], <=======***HERE***=========
  "MinimumLevel": "Debug",
  "WriteTo": [
    { "Name": "Console" },
    {
      "Name": "RollingFile",
      "Args": {
        "pathFormat": "logs\\log-{Date}.txt",
        "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
      }
    }
  ],
  "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
  "Properties": {
    "Application": "My Application"
  }
}

在上面的示例中,我们使用了File接收器没有将其添加到Using属性中。但是,一切似乎都正常。

所以我无法确切理解为什么我们基本上需要这个Using。有人可以给我解释一下吗?

1 个答案:

答案 0 :(得分:3)

Serilog.Settings.Configuration的文档中对此进行了介绍:

  

(此程序包使用DependencyContext来实现约定,以在名称中任何位置找到任何带有Serilog的程序包,并从中提取配置方法,因此上面的Using示例是多余的。)< / p>

这意味着它用于定义用于查找Serilog接收器的软件包,但是在使用Serilog.Settings.Configuration软件包时是多余的。


更多信息

我已经看过Serilog源代码,以便能够提供确切的信息Using以及为什么首先需要使用它的更多信息。希望以下说明对您有所帮助。

请考虑以下基于代码的设置:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

在此示例中,ConsoleLoggerSinkConfiguration的扩展方法(因此,它以LoggerSinkConfiguration的实例为第一个参数)。使用这种基于代码的方法时,只有在引用的程序集中可以找到此扩展方法时,代码才会编译。

接下来,考虑以下方法,该方法使用基于IConfiguration的方法:

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(someConfiguration)
    .CreateLogger();
{
    "Serilog": {
        "Using": ["Serilog.Sinks.Console"], // Redundant.
        "WriteTo": ["Console"]
    }
}

在此示例中,编译过程不知道JSON字符串值"Console"指的是什么,因此需要一个可以从字符串"Console"到{{1 }}上面提到的扩展方法。为此,Serilog需要在运行时首先找到扩展方法 (在本示例中,扩展方法位于Console()程序集中)。

此查找过程是使用反射完成的,反射将对find public static methods that take as their first parameter a LoggerSinkConfiguration进行一些汇编扫描。寻找这些扩展方法时,您在问题中询问的Serilog.Sinks.Console指令是mechanism for helping determine exactly which assemblies should be scanned

如文档所述,基于Using的方法使用IConfigurationautomatically scan assemblies that have Serilog in their name。由于DependencyContext 确实的名称中带有Serilog.Sinks.Console,因此无需将其添加到Serilog指令中。使用此方法时,您还可以选择provide your own DependencyContext instance,因此在寻找接收器时可能需要明确说明要扫描的程序集。