繁体   English   中英

不能为 serilog 配置自定义接收器

[英]Сan't configure a custom sink for a serilog

我无法通过配置文件将自定义接收器连接到记录器。 我在.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/13151982 https://stackoverflow.com/a/24922105/13151982

但出于某种原因,这对我不起作用。

为了重现这个问题,我制作了一个简约的应用程序。 也不起作用,就像在我的主要项目中一样。

示例应用程序.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的扩展方法class 您自己实例化接收器并将其添加到管道中的位置。

在您的情况下,它将是这样的:

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM