Serilog JSON 配置中的 "Using" 有什么作用?
What does "Using" in Serilog JSON configuration do?
在 Serilog JSON 配置中 Using
实际上做了什么(例如在 .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
sink WITHOUT 将其添加到 Using
属性。但是,似乎一切正常。
所以我不明白为什么我们基本上需要这个 Using
。有人可以给我解释一下吗?
这包含在 Serilog.Settings.Configuration
的文档中:
(This package implements a convention using DependencyContext
to find any package with Serilog
anywhere in the name and pulls configuration methods from it, so the Using
example above is redundant.)
这意味着它用于定义哪些包用于定位 Serilog 接收器,但在使用 Serilog.Settings.Configuration
包时它是多余的。
更多信息
我查看了 Serilog 源代码,以便能够提供更多关于 Using
的确切功能以及为什么首先需要它的信息。希望以下解释对您有所帮助。
考虑以下基于代码的设置:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
在此示例中,Console
是 LoggerSinkConfiguration
的扩展方法(因此它采用 LoggerSinkConfiguration
的实例作为其第一个参数)。使用这种基于代码的方法时,仅当可以在引用的程序集中找到此扩展方法时,代码才会编译。
接下来,考虑以下方法,它使用基于 IConfiguration
的方法:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(someConfiguration)
.CreateLogger();
{
"Serilog": {
"Using": ["Serilog.Sinks.Console"], // Redundant.
"WriteTo": ["Console"]
}
}
在此示例中,编译过程不知道 JSON 字符串值 "Console"
指的是什么,因此需要一个可以从字符串 "Console"
到上面提到的 Console()
扩展方法。为了做到这一点,Serilog 需要首先 找到 扩展方法 在运行时 (在这个例子中,它位于 Serilog.Sinks.Console
组装)。
这个查找过程是使用反射完成的,它在寻找这些扩展方法时对 find public static
methods that take as their first parameter a LoggerSinkConfiguration
. The Using
directive you've asked about in your question is a mechanism for helping determine exactly which assemblies should be scanned 进行了一些汇编扫描。
如文档所述,基于 IConfiguration
的方法使用 DependencyContext
以便在使用此方法时 automatically scan assemblies that have Serilog
in their name. Because Serilog.Sinks.Console
does have Serilog
in its name, there's no need to add this to the Using
directive. You also have the option to provide your own DependencyContext
instance,因此您可能需要明确说明要使用哪些程序集寻找水槽时扫描。
在 Serilog JSON 配置中 Using
实际上做了什么(例如在 .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
sink WITHOUT 将其添加到 Using
属性。但是,似乎一切正常。
所以我不明白为什么我们基本上需要这个 Using
。有人可以给我解释一下吗?
这包含在 Serilog.Settings.Configuration
的文档中:
(This package implements a convention using
DependencyContext
to find any package withSerilog
anywhere in the name and pulls configuration methods from it, so theUsing
example above is redundant.)
这意味着它用于定义哪些包用于定位 Serilog 接收器,但在使用 Serilog.Settings.Configuration
包时它是多余的。
更多信息
我查看了 Serilog 源代码,以便能够提供更多关于 Using
的确切功能以及为什么首先需要它的信息。希望以下解释对您有所帮助。
考虑以下基于代码的设置:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
在此示例中,Console
是 LoggerSinkConfiguration
的扩展方法(因此它采用 LoggerSinkConfiguration
的实例作为其第一个参数)。使用这种基于代码的方法时,仅当可以在引用的程序集中找到此扩展方法时,代码才会编译。
接下来,考虑以下方法,它使用基于 IConfiguration
的方法:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(someConfiguration)
.CreateLogger();
{
"Serilog": {
"Using": ["Serilog.Sinks.Console"], // Redundant.
"WriteTo": ["Console"]
}
}
在此示例中,编译过程不知道 JSON 字符串值 "Console"
指的是什么,因此需要一个可以从字符串 "Console"
到上面提到的 Console()
扩展方法。为了做到这一点,Serilog 需要首先 找到 扩展方法 在运行时 (在这个例子中,它位于 Serilog.Sinks.Console
组装)。
这个查找过程是使用反射完成的,它在寻找这些扩展方法时对 find public static
methods that take as their first parameter a LoggerSinkConfiguration
. The Using
directive you've asked about in your question is a mechanism for helping determine exactly which assemblies should be scanned 进行了一些汇编扫描。
如文档所述,基于 IConfiguration
的方法使用 DependencyContext
以便在使用此方法时 automatically scan assemblies that have Serilog
in their name. Because Serilog.Sinks.Console
does have Serilog
in its name, there's no need to add this to the Using
directive. You also have the option to provide your own DependencyContext
instance,因此您可能需要明确说明要使用哪些程序集寻找水槽时扫描。