Переопределение параметров NLog с помощью конфигурации Azure

У меня есть приложение, работающее в 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 я создал следующую запись «Параметры приложения»:

Имя Ценить NLog:правила [{"logger": "microsoft.","maxLevel": "Отладка","final": true},{"logger": "","minLevel": "Предупреждение","writeTo": "база данных"} ]

Я думаю, что либо вызов LoadConfigurationFromAppSettings() происходит слишком рано, либо он игнорирует обновленные значения, но, конечно, я могу просто ошибаться в том, что пытаюсь сделать.

Любая помощь будет отличной

Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
0
64
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Пара "ключ-значение" ("NLog:rules"), созданная в конфигурации приложений Azure, представляет собой объект JSON. Убедитесь, что вы установили для него тип контента JSON. В противном случае он будет загружен как строка. Дополнительные сведения см. в разделе Использование типа контента для хранения ключей и значений JSON в конфигурации приложения.

Я не вижу вашего кода, который загружает данные из конфигурации приложений Azure.

Поэтому я не мог заставить это работать так, как я думал, — просто заменяя текущие правила — но я заставил это работать так, как мне нужно. Все, что я действительно хотел сделать, это изменить минимальный уровень для правила базы данных, чтобы я мог настроить его без обновления кода.

В итоге я добавил параметр приложения в конфигурацию приложения 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

Другие вопросы по теме