Как настроить поставщика ведения журналов EventLog через мой файл appsettings.json
В консольном приложении My .net core 6 я создаю хост-строитель
var builder = Host.CreateDefaultBuilder(args);
Это дает мне экземпляр HostBuilder с фабрикой ведения журналов, настроенной для поставщиков консоли, отладки, журнала событий и источников событий, а также поставщиков конфигурации для переменных пользовательской/системной среды, appsettings.json, appsettings..json и т. д.
Я могу внедрить ILogger или ILoggingFactory в свой класс и писать во все поставщики журналов, используя функцию ILogger.Log.
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();
}
}
Теперь я хочу настроить имя приложения журнала событий и имя источника, в которое будет записывать провайдер журнала событий. Я бы не хотел жестко кодировать это, поэтому я надеялся сделать это через файл appsettings.json. Кажется, я не могу заставить это подействовать. Мой файл appsettings.json выглядит так:
{
"Logging":
{
//Settings for the windows event log logging provider
"EventLog":
{
"LogName": "Application",
"SourceName": "MySource",
"LogLevel":
{
"Default": "Trace"
}
}
}
}
Вышеупомянутые настройки приложения не влияют, поэтому я решил попробовать добавить нового провайдера EventLog и передать ему конфигурацию.
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureAppConfiguration((context, builder) =>
{
var eventLogConfiguration = context.Configuration.GetSection("Logging:EventLog").Get<EventLogSettings>();
builder.AddEventLog(eventLogConfiguration);
});
Это тоже не сработало, поэтому я попытался очистить поставщиков журналов на случай, если добавление дубликатов будет проблемой.
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureAppConfiguration((context, builder) =>
{
builder.ClearProviders();
var eventLogConfiguration = context.Configuration.GetSection("Logging:EventLog").Get<EventLogSettings>();
builder.AddEventLog(eventLogConfiguration);
});
Это работает, но что, если я хочу, чтобы все остальные существующие поставщики были сохранены? Могу ли я просто заменить один или каким-то образом применить конфигурацию к существующему провайдеру, или есть какой-то другой/лучший способ сделать это?
1 ответ
Если вы посмотрите на источник , он уже делает все это:
// HostingHostBuilderExtensions.cs > AddDefaultServices
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
...
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
...
if (isWindows)
// Add the EventLogLoggerProvider on windows machines
logging.AddEventLog();
При условииAddConfiguration
Звонок вам не нужен.
Учитывая этот вызов, вам не нужно вызывать его снова.
Поскольку это работает только тогда, когда вы сначала звоните, я думаюCreateDefaultBuilder
должно быть, неправильно настроен журнал событий. Но, если бы это было такGetSection("Logging:EventLog")
завершится ошибкой или вы увидите сообщение об ошибке (как это происходит, если вы используете нераспознанный источник или имя журнала).
Интересно, если что-то вLogging
этого нет вLogging:EventLog
может быть проблема?
У меня похожая проблема , но мне не нужно звонитьClearProviders()
- добавлениеAddEventLog
мне достаточно, но это ничего не улавливаетappsettings.json
если я не добавлю это явно.
Обновлять
Я думаю, что это может быть ошибка (или, возможно,LogName
иSourceName
просто не поддерживаются из конфигурации). У меня есть обходной путь на данный момент.
По сути, я вручную устанавливаю конфигурацию (как и вы), но с проверкой ОС, которую понимает анализ кода, и с лямбдой, которая изменяет конфигурацию, а не применяет ее снова.
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
public static void SetEventLogConfig(WebApplicationBuilder builder) {
string? eventLog = builder.Configuration["Logging:EventLog:SourceName"];
if(eventLog is not null)
builder.Logging.AddEventLog(c => c.SourceName = eventLog);
}
// then in program.cs
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
SetEventLogConfig(builder);
Это работает для моего приложения, но я до сих пор не уверен, зачем вам нужно звонитьClearProviders
в вашей реализации.