In My .net core 6 console app I create a host builder
var builder = Host.CreateDefaultBuilder(args);
This gives me a HostBuilder instance with a logging factory set up for console, debug, event log, and event source providers, as well as configuration providers for user/system environment vars, appsettings.json, appsettings..json, etc.
I can inject ILogger or ILoggingFactory into my class and write to all the logging providers using the ILogger.Log function.
public class BusinessLogic
{
private IHostEnvironment _env;
private ILogger _logger;
public BusinessLogic(
IHostEnvironment env,
ILoggerFactory loggerFactor)
{
_env = env;
_logger = loggerFactor.CreateLogger<BusinessLogic>();
}
public void Run()
{
foreach (var level in Enum.GetValues<LogLevel>())
{
_logger.Log(level, $"Test logging at level {level}.");
}
Console.WriteLine("Hello, World! Press any key...");
Console.ReadLine();
}
}
Now I want to configure the event log application name and source name that the event log provider will write to. I'd rather not hard code this, so I was hoping to do this throught he appsettings.json file. I can't seem to get it to take affect. My appsettings.json file looks like this:
{
"Logging":
{
//Settings for the windows event log logging provider
"EventLog":
{
"LogName": "Application",
"SourceName": "MySource",
"LogLevel":
{
"Default": "Trace"
}
}
}
}
The above appsettings has no affect, so I thought I would try adding a new EventLog provider and pass it the configuration.
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureAppConfiguration((context, builder) =>
{
var eventLogConfiguration = context.Configuration.GetSection("Logging:EventLog").Get<EventLogSettings>();
builder.AddEventLog(eventLogConfiguration);
});
That didn't work either, so I tried clearing the logging providers, in case adding duplicates was an issue.
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureAppConfiguration((context, builder) =>
{
builder.ClearProviders();
var eventLogConfiguration = context.Configuration.GetSection("Logging:EventLog").Get<EventLogSettings>();
builder.AddEventLog(eventLogConfiguration);
});
That works, but what if I want all the other existing providers to be retained? Can I just replace one, or somehow apply the configuration to an existing provider, or is there some other/better way to do this?
If you look at the source for
CreateDefaultBuilderit appears to already do all this:Given that
AddConfigurationcall you shouldn't needGetSection("Logging:EventLog").Given that
AddEventLogcall you shouldn't need to call it again.As it only works when you call
ClearProviders()first I thinkCreateDefaultBuildermust be misconfiguring the event log somehow. But, if that were the caseGetSection("Logging:EventLog")would fail or you'd see an error (as happens if you useAddEventLogwith an unrecognised source or log name).I wonder if something in
Loggingthat isn't inLogging:EventLogcould be the problem?I'm having a similar issue, but I don't have to call
ClearProviders()- addingAddEventLogis enough for me, but that doesn't pick up anything fromappsettings.jsonunless I add it explicitly.Update
I think this might be a bug (or possibly
LogNameandSourceNamejust aren't supported from config). I have a workaround for now.Basically, I manually set the config (like you), but with an OS check that code analysis understands and with the lambda that alters the config rather than applying it again.
That works for my app, but I'm still not sure why you need to call
ClearProvidersin your implementation.