简体   繁体   中英

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

I'm trying to wrap the configuration of the Serilog.Sinks.Elasticsearch sink so that my log configuration looks something like this.

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

My inspiration came from this answer , but I'm stuck with the internal condition logic, specifically if the the sink is disabled.

Here is what I have so far.

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?
    }
}

So my question is how to propagate the configuration when the internal sink is disabled, and I need to pass the original configuration on to the next sink in the chain?

There are a few properties of the configuration object, Logger, Sink, and Sink<> but I'm unsure of which to use, and more importantly, correctly.

This will work:

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

But, conditionally configuring the logger would, too:

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

I know I'm late to the party here. But this is how I did it to keep the fluent approach.

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

Call with:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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