我无法通过配置文件将自定义接收器连接到日志记录器。我在。net 5和。net Core 3.1下试过。
我研究了文档:https://github.com/serilog/serilog-settings-configuration using-section-and-auto-discovery-of-configuration-assemblies
我还看到了对相同请求的响应。https://stackoverflow.com/a/50118486/13151982https://stackoverflow.com/a/24922105/13151982
但由于某些原因,这对我不起作用。
为了重现这个问题,我制作了一个极简的应用程序。也不工作,在我的主要项目。
SampleApp.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
简单自定义接收器:
public class SerilogCounterSink : ILogEventSink
{
private static int i = 0;
public void Emit(LogEvent logEvent)
{
i++;
}
}
配置:
var builder = new ConfigurationBuilder();
ConfigSetup(builder);
// defining Serilog configs
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Build())
.Enrich.FromLogContext()
.WriteTo.Console()
//.WriteTo.Sink(new SerilogCounterSink()) //works if uncomment this line
.CreateLogger();
// Initiated the denpendency injection container
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) => {
services.AddTransient<IDataService, DataService>();
})
.UseSerilog()
.Build();
配置文件:
"Serilog": {
"Using": [ "SampleApp" ],
"WriteTo": [
{ "Name": "SerilogCounterSink" },
{ "Name": "Console" },
{
"Name": "File",
"Args": { "path": "Logs/log.txt" }
}
],
"MinimalLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Information"
}
}
}
我试过了:
"WriteTo": [
{ "Name": "SampleApp.SerilogCounterSink" },
"WriteTo": [
{ "Name": "SerilogCounter" },
"WriteTo": [
{ "Name": "SampleApp.SerilogCounter" },
因此,当写
时_log.LogInformation("test");
我没有进入SerilogCounterSink。Emit(在那里放置一个断点)。如果我取消注释以编程方式添加自定义接收器的一行代码,那么一切都可以工作-我进入方法。
Serilog配置扩展不直接创建接收器的实例。它所做的只是尝试调用一个方法.WriteTo.NameOfTheSinkYouDefinedInTheConfig()
,如果存在的话——所以为了工作,你需要自己提供这个方法。
如果您查看任何官方接收器的源代码,您会注意到它们总是被声明为internal
类而不是public
类,并且将接收器连接到Serilog配置的方法是通过创建LoggerSinkConfiguration
类的扩展方法,您可以在其中实例化接收器并将其添加到管道中。
在你的例子中,应该是这样的:
public static class SerilogCounterLoggerConfigurationExtensions
{
public static LoggerConfiguration SerilogCounterSink(
this LoggerSinkConfiguration sinkConfiguration)
{
return sinkConfiguration.Sink(new SerilogCounterSink(), LevelAlias.Minimum,
levelSwitch: null);
}
}
现在扩展方法可用,配置扩展将能够以您在代码中所做的方式调用它:
Log.Logger = new LoggerConfiguration()
.WriteTo.SerilogCounterSink() // <<<<<<<<<<<<<<
.CreateLogger();