簡體   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