serilog / serilog-extensions-logging

Serilog provider for Microsoft.Extensions.Logging
Apache License 2.0
307 stars 97 forks source link

Adds an overload that exposes the ServiceProvider of the ILoggingBuilder #204

Closed Luiz-Ossinho closed 2 years ago

Luiz-Ossinho commented 2 years ago

This allows for configuration that requires dependency injection, such as the following use case.

// Pretend that PocoLoggingOptions is a POCO configured with the logging options.

services.AddLogging(logging =>
        logging
        .ClearProviders()
        .AddSerilog(serviceProvider =>
        {
            var loggingOptions = serviceProvider.GetRequiredService<IOptionsSnapshot<PocoLoggingOptions>>().Value;

            var elasticSearchOptions = new ElasticsearchSinkOptions(new Uri(loggingOptions.Uri))
            {
                ModifyConnectionSettings = auth =>
                    auth.BasicAuthentication(loggingOptions.Logging.Username, loggingOptions.Password),
                BufferBaseFilename = loggingOptions.BufferPath
            };

            return new LoggerConfiguration()
                .WriteTo.Elasticsearch(elasticSearchOptions)
                .CreateLogger();
        })
);
nblumhardt commented 2 years ago

Thank you @Luiz-Ossinho.

Most of the effort around higher-level configuration APIs is going into https://github.com/serilog/serilog-extensions-hosting and UseSerilog(); if you're able to switch to it you'll find the IServiceProvider is supplied as an argument to UseSerilog()'s configuration callback.

If not, you should be able to use the service provider in configuration here with something like:

services.AddLogging(logging =>
{
        logging.ClearProviders();

        var loggingOptions = serviceProvider.GetRequiredService<IOptionsSnapshot<PocoLoggingOptions>>().Value;

        var elasticSearchOptions = new ElasticsearchSinkOptions(new Uri(loggingOptions.Uri))
        {
            ModifyConnectionSettings = auth =>
                    auth.BasicAuthentication(loggingOptions.Logging.Username, loggingOptions.Password),
            BufferBaseFilename = loggingOptions.BufferPath
        };

        logging.Services.AddSingleton<ILoggerProvider, SerilogLoggerProvider>(services =>
            new SerilogLoggerProvider(new LoggerConfiguration()
                .WriteTo.Elasticsearch(elasticSearchOptions)
                .CreateLogger(), true));

        logging.AddFilter<SerilogLoggerProvider>(null, LogLevel.Trace);
});

Does that help?

Luiz-Ossinho commented 2 years ago

The UseSerilog() suggestion really helped. Thanks a lot. This makes this PR unnecessary. For anyone wondering, this is how i implemented the same logging configuration with UseSerilog()

(builder.Host as IHostBuilder).UseSerilog((ctx, serviceProvider, loggingConfig) =>
{
      var loggingOptions = serviceProvider.GetRequiredService<IOptionsSnapshot<PocoLoggingOptions>>().Value;

      var elasticSearchOptions = new ElasticsearchSinkOptions(new Uri(loggingOptions.Logging.Url))
      {
          ModifyConnectionSettings = auth =>
              auth.BasicAuthentication(loggingOptions.Logging.Username, loggingOptions.Logging.Password),
          BufferBaseFilename = loggingOptions.Logging.BufferPath
      };

      loggingConfig.WriteTo.Elasticsearch(elasticSearchOptions);
});