У меня есть приложение, работающее в Azure и регистрирующееся в базе данных. У меня есть настройки NLog из файла appsettings.json, и, похоже, все работает хорошо. Однако теперь я хотел бы переопределить правила ведения журнала, добавив параметр приложения в конфигурацию приложения в Azure, и это не удается.
Это запись NLog в файле settings.json приложения:
"NLog": {
"autoReload": true,
"throwConfigExceptions": true,
//"internalLogLevel": "Info",
//"internalLogFile": "x:/internal-nlog.txt",
"extensions": [
{ "assembly": "NLog.Extensions.Logging" },
{ "assembly": "NLog.Web.AspNetCore" },
{ "assembly": "NLog.Database" }
],
"targets": {
"async": true,
"database": {
"type": "Database",
"dbProvider": "System.Data.SqlClient",
"connectionString": "<Connection String>",
"keepConnection": "true",
"commandText": "insert into LoggingMessages(Created, MessageType, Message, CallSite, ExceptionDetail) values(getutcdate(), @level, @message, @callsite, @exception);",
"parameters": [
{
"name": "@level",
"layout": "${level}"
},
{
"name": "@message",
"layout": "${message}"
},
{
"name": "@logger",
"layout": "${logger}"
},
{
"name": "@callsite",
"layout": "${callsite}"
},
{
"name": "@exception",
"layout": "${exception:tostring}"
}
]
},
"logconsole": {
"type": "Console"
}
},
"rules": [
{
"logger": "microsoft.*",
"maxLevel": "Debug",
"final": true
},
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "database"
}
]
}
Эта строка находится в методе конфигурации моего startup.cs:
var logger = LogManager.Setup()
.LoadConfigurationFromAppSettings()
.GetCurrentClassLogger();
И мой метод CreateHostBuilder в program.cs выглядит так:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseNLog();
Затем на экране «Конфигурация приложения» на портале Azure я создал следующую запись «Параметры приложения»:
Я думаю, что либо вызов LoadConfigurationFromAppSettings() происходит слишком рано, либо он игнорирует обновленные значения, но, конечно, я могу просто ошибаться в том, что пытаюсь сделать.
Любая помощь будет отличной


Пара "ключ-значение" ("NLog:rules"), созданная в конфигурации приложений Azure, представляет собой объект JSON. Убедитесь, что вы установили для него тип контента JSON. В противном случае он будет загружен как строка. Дополнительные сведения см. в разделе Использование типа контента для хранения ключей и значений JSON в конфигурации приложения.
Я не вижу вашего кода, который загружает данные из конфигурации приложений Azure.
IConfiguration.Поэтому я не мог заставить это работать так, как я думал, — просто заменяя текущие правила — но я заставил это работать так, как мне нужно. Все, что я действительно хотел сделать, это изменить минимальный уровень для правила базы данных, чтобы я мог настроить его без обновления кода.
В итоге я добавил параметр приложения в конфигурацию приложения Azure: |Имя|Значение| |----|-----| |Уровень ведения журнала|Отладка|
затем добавьте некоторый код, подобный следующему, в метод конфигурации файла startup.cs после существующей строки настройки LogManager.
var loggingLevel = Configuration.GetValue<string>("LoggingLevel");
var haveNewLoggingLevel = !string.IsNullOrWhiteSpace(loggingLevel);
// only interested in the 'database' target
var databaseTarget = LogManager.Configuration.FindTargetByName("database") as DatabaseTarget;
if ((databaseTarget != null) && haveNewLoggingLevel)
{
var rules = LogManager.Configuration.LoggingRules;
foreach (var rule in rules)
{
if (rule.Targets.Contains(databaseTarget))
{
rule.SetLoggingLevels(NLog.LogLevel.FromString(loggingLevel), NLog.LogLevel.Fatal);
}
}
LogManager.ReconfigExistingLoggers();
}
Благодаря этому я смог добиться того, что мне было нужно, но я не уверен, что это отвечает на вопрос, который я изначально задал. Я также добавил аналогичный код для обновления строки подключения к базе данных из настроек приложения.
Возможно, добавьте параметр приложения в конфигурацию приложения Azure:
И используйте ${configsetting:LoggingLevel} в правиле ведения журнала NLog:
"NLog": {
"autoReload": true,
"throwConfigExceptions": true,
"extensions": [
{ "assembly": "NLog.Extensions.Logging" },
{ "assembly": "NLog.Web.AspNetCore" },
{ "assembly": "NLog.Database" }
],
"targets": {
"async": true,
"database": {
"type": "Database",
"dbProvider": "System.Data.SqlClient",
"connectionString": "<Connection String>",
"keepConnection": "true",
"commandText": "insert into LoggingMessages(Created, MessageType, Message, CallSite, ExceptionDetail) values(getutcdate(), @level, @message, @callsite, @exception);",
"parameters": [
{
"name": "@level",
"layout": "${level}"
},
{
"name": "@message",
"layout": "${message}"
},
{
"name": "@logger",
"layout": "${logger}"
},
{
"name": "@callsite",
"layout": "${callsite}"
},
{
"name": "@exception",
"layout": "${exception:tostring}"
}
]
},
"logconsole": {
"type": "Console"
}
},
"rules": [
{
"logger": "microsoft.*",
"maxLevel": "Debug",
"final": true
},
{
"logger": "*",
"minLevel": "${configsetting:LoggingLevel:whenEmpty=Trace}",
"writeTo": "database"
}
]
}
См. также: https://github.com/NLog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules
См. также: https://github.com/NLog/NLog/wiki/ConfigSetting-Layout-Renderer
Чтобы переопределить вложенное значение внутри appsettings.json с помощью конфигурации приложений Azure, необходимо использовать __.
Например, ApplicationInsights__InstrumentationKey переопределит это значение в appsettings.json.
"ApplicationInsights": {
"InstrumentationKey": "Will be overrridden"
}
См. также: https://learn.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal
Обратите внимание, что для переопределения вложенного значения внутри json-массива требуется дополнительная магия (например, определенное правило NLog). Вам нужно украсить json-array-index-name. См. также: https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-configuration-with-appsettings.json#logging-rule-override