如何创建支持配置逻辑的 Serilog Sink Extension

How to create a Serilog Sink Extension that will support configuration logic

我正在尝试包装 Serilog.Sinks.Elasticsearch 接收器的配置,以便我的日志配置看起来像这样。

    var logger = Log.Logger = new LoggerConfiguration()
          .ReadFrom.AppSettings()
          .Enrich.FromLogContext()
          .Enrich.WithMachineName()
          .Enrich.WithProcessId()
          .Enrich.WithThreadId()
          .WriteTo.ElasticsearchIfEnabled() // <--- Chained Sink
          .WriteTo.Async(
              a => a.File(
                  filePath,
                  outputTemplate: CanonicalTemplate,
                  retainedFileCountLimit: 31,
                  rollingInterval: RollingInterval.Day,
                  rollOnFileSizeLimit: true,
                  buffered: true,
                  flushToDiskInterval: TimeSpan.FromMilliseconds(500)))
        .CreateLogger();

我的灵感来自于此 ,但我坚持使用内部条件逻辑,特别是在接收器被禁用的情况下。

这是我目前的情况。

public static class MyConfigExtensions
{
    public static LoggerConfiguration ElasticsearchIfEnabled(this LoggerSinkConfiguration loggerSinkConfiguration)
    {
        var isElasticSinkEnabled = GetThisValue();

        if (isElasticSinkEnabled)
        {
            // Code necessary to configure sink....

            return loggerSinkConfiguration.Sink(new ElasticsearchSink(elasticSearchSinkOptions));
        }

        return loggerSinkConfiguration; // <-- what is passed here that will propagate the configuration?
    }
}

所以我的问题是当内部接收器被禁用时如何传播配置,我需要将原始配置传递到链中的下一个接收器?

配置对象有几个属性,Logger、Sink 和 Sink<>,但我不确定要使用哪个,更重要的是,是否正确使用。

这会起作用:

return loggerSinkConfiguration.Sink(new LoggerConfiguration().CreateLogger());

但是,有条件地配置记录器也会:

var configuration = new LoggerConfiguration()
      .ReadFrom.AppSettings()
      .Enrich.FromLogContext()
      .Enrich.WithMachineName()
      .Enrich.WithProcessId()
      .Enrich.WithThreadId();

if (isElasticSinkEnabled)
    configuration.WriteTo.ElasticsearchIfEnabled();

var logger = Log.Logger = configuration.WriteTo.Async(
          a => a.File(
              filePath,
              outputTemplate: CanonicalTemplate,
              retainedFileCountLimit: 31,
              rollingInterval: RollingInterval.Day,
              rollOnFileSizeLimit: true,
              buffered: true,
              flushToDiskInterval: TimeSpan.FromMilliseconds(500)))
    .CreateLogger();

我知道我来晚了。但是为了保持流畅的方法,我就是这样做的。

  public static class SerilogExtensions
    {
        public static LoggerConfiguration If(this LoggerConfiguration loggerConfiguration, Func<bool> condition, Func<LoggerConfiguration, LoggerConfiguration> func)
        {
            return !condition.Invoke() ? loggerConfiguration : func.Invoke(loggerConfiguration);
        }
    }

通话方式:

Log.Logger = new LoggerConfiguration()
   .WriteTo.Debug()
   .If(() => true, x => x.WriteTo.Console())
   .CreateLogger();