How to create a LoggerFactory with a ConsoleLoggerProvider?
.Net Coreasp.net Core-2.2.Net Core Problem Overview
The ConsoleLoggerProvider has four constructors:
ConsoleLoggerProvider(IConsoleLoggerSettings)
ConsoleLoggerProvider(IOptionsMonitor<ConsoleLoggerOptions>)
ConsoleLoggerProvider(Func<String,LogLevel,Boolean>, Boolean)
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
}
)