How to create a LoggerFactory with a ConsoleLoggerProvider?

.Net Coreasp.net Core-2.2

.Net Core Problem Overview


The ConsoleLoggerProvider has four constructors:

  1. ConsoleLoggerProvider(IConsoleLoggerSettings)
  2. ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions>)
  3. ConsoleLoggerProvider(Func<String,LogLevel,Boolean>, Boolean)
  4. ConsoleLoggerProvider(Func<String,LogLevel,Boolean>, Boolean, Boolean)

Three of them are declared obsolete with this message: > This method is obsolete and will be removed in a future version. The recommended alternative is using LoggerFactory to configure filtering and ConsoleLoggerOptions to configure logging options.

With constructor #3, creating a LoggerFactory with a ConsoleLoggerProvider is straightforward (as documented on Entity Framework Core - Logging):

var loggerFactory = new LoggerFactory(new[] { new ConsoleLoggerProvider((category, level) => level >= LogLevel.Information, true) });

But since it's deprecated, we are left with constructor #2. Here's what I found to be equivalent:

var configureNamedOptions = new ConfigureNamedOptions<ConsoleLoggerOptions>("", null);
var optionsFactory = new OptionsFactory<ConsoleLoggerOptions>(new []{ configureNamedOptions }, Enumerable.Empty<IPostConfigureOptions<ConsoleLoggerOptions>>());
var optionsMonitor = new OptionsMonitor<ConsoleLoggerOptions>(optionsFactory, Enumerable.Empty<IOptionsChangeTokenSource<ConsoleLoggerOptions>>(), new OptionsCache<ConsoleLoggerOptions>());
var loggerFactory = new LoggerFactory(new[] { new ConsoleLoggerProvider(optionsMonitor) }, new LoggerFilterOptions { MinLevel = LogLevel.Information });

This seems overly complicated, am I missing something simpler?

.Net Core Solutions


Solution 1 - .Net Core

In .NET Core 2.2, you can build an ILoggerFactory without using obsolete methods through Microsoft's dependency injection framework. It's a little less verbose than the version where everything is constructed by hand. Here’s how:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder
    .AddConsole()
    .AddFilter(level => level >= LogLevel.Information)
);
var loggerFactory = serviceCollection.BuildServiceProvider().GetService<ILoggerFactory>();

And in .NET Core 3.0, you can use LoggerFactory.Create:

var loggerFactory = LoggerFactory.Create(builder => {
        builder.AddFilter("Microsoft", LogLevel.Warning)
               .AddFilter("System", LogLevel.Warning)
               .AddFilter("SampleApp.Program", LogLevel.Debug)
               .AddConsole();
    }
);

See also:

Solution 2 - .Net Core

Just in case, if someone wants to do it in ASP.NET Core composition root for efcore:

services.AddDbContext<DbContext>(opt => {
	opt.AddSqlServer(Configuration.GetConnectionString("DefaultConnection"));
	opt.UseLoggerFactory(LoggerFactory.Create(builder => { builder.AddConsole(); }));
});

Solution 3 - .Net Core

@0xced thanks for your deconstructed example, since delegates don't work in Powershell this helped me to do the same in Powershell:

$optionsFactory = [OptionsFactory[ConsoleLoggerOptions]]::new(
    [List[ConfigureNamedOptions[ConsoleLoggerOptions]]]@(
        [ConfigureNamedOptions[ConsoleLoggerOptions]]::new('',$null)
    ),
    [List[IPostConfigureOptions[ConsoleLoggerOptions]]]::new()
)

$optionsMonitor = [OptionsMonitor[ConsoleLoggerOptions]]::new(
    $optionsFactory,
    [List[IOptionsChangeTokenSource[ConsoleLoggerOptions]]]::new(),
    [OptionsCache[ConsoleLoggerOptions]]::new()
)

$consoleLoggerProvider = [ConsoleLoggerProvider]$OptionsMonitor
$consoleLoggerProviderList = [List[ILoggerProvider]]::new()
$consoleLoggerProviderList.add($consoleLoggerProvider)

$loggerFactory = [LoggerFactory]::new(
    $consoleLoggerProviderList,
    [LoggerFilterOptions]@{
        MinLevel = [LogLevel]::Information
    }
)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question0xcedView Question on Stackoverflow
Solution 1 - .Net Core0xcedView Answer on Stackoverflow
Solution 2 - .Net CoreDaniel BView Answer on Stackoverflow
Solution 3 - .Net CoreJustin GroteView Answer on Stackoverflow