Подтвердить что ты не робот

Реконфигурирование NLog программно

Это мой первый раз, когда я использовал пакет NLog для регистрации, но до сих пор он отлично работал.

В моем сценарии мне нужно инициализировать мои настройки NLog LoggingConfiguration программным способом, а не более типичным сценарием конфигурационного файла. Я протестировал это и получил все, что мне нужно, по умолчанию. Но как я могу изменить свои настройки программно во время выполнения? Вероятно, наиболее распространенным сценарием здесь является тот, где уровень ведения журнала приложения по умолчанию установлен на ОШИБКУ, но в определенном модуле возникает ошибка, которую я хочу переключить уровень ведения журнала, чтобы быть более подробным для отслеживания ошибки. Я хотел бы написать небольшой веб-интерфейс, чтобы я мог легко настроить эти параметры во время выполнения, но я хочу убедиться, что с этим согласен.

4b9b3361

Ответ 1

Я знаю, что я опаздываю на год, но я просто столкнулся с похожим сценарием, где мне нужно было обеспечить динамический контроль регистратора для пользователей. К счастью, это относительно легко с nlog. Здесь я просто включаю протоколирование уровня трассировки в уже созданный Logger, но, очевидно, вы можете делать все, что хотите, включая добавление новых Targets/Rules или просто полностью заменить LoggerConfiguration на свой программно сгенерированный файл.

Базовый ColoredConsole nlog.config:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target xsi:type="ColoredConsole" name="c"
            layout="${longdate} ${uppercase:${level}} ${message}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Error" writeTo="c" />
  </rules>
</nlog>

Простое консольное приложение:

public class Program 
{
  //Initialize default Logger from config file
  private static readonly Logger m_log = LogManager.GetCurrentClassLogger();

  public static Logger Log 
  {
      get { return m_log; }
  }

  public static void Main(string[] args) 
  {
    Log.Trace("You won't see me because config is at LogLevel.Error");
    EnabledTraceForAllRules();
    Log.Trace("You will see me now though!");

    //Pause console window
    Console.WriteLine("Press any key to continue...");
    Console.ReadKey(true);

    /* Prints:
    2013-05-07 16:04:22.7050 TRACE You will see me now though!
    Press any key to continue...
    */
  }

  public static void EnabledTraceForAllRules() 
  {
    foreach(var rule in LogManager.Configuration.LoggingRules)
    {
      rule.EnableLoggingForLevel(LogLevel.Trace);
    }

    //Call to update existing Loggers created with GetLogger() or 
    //GetCurrentClassLogger()
    LogManager.ReconfigExistingLoggers();
  }
}

Если вам нужно изменить конфигурацию ведения журнала вне процесса, и это необходимо сделать программным способом, я бы предложил пойти с WCF. Вы можете открыть небольшую службу WCF из своего приложения или веб-сайта, который предоставляет методы для перенастройки nlog.

Ответ 3

Программный начальный пример установки приведен на странице учебника NLog здесь, который я включил ниже. (Там немного более обширная версия здесь.)

public static void Startup()
{
    var config = new NLog.Config.LoggingConfiguration();

    // Targets where to log to: File and Console
    var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "file.txt" };
    var logconsole = new NLog.Targets.ConsoleTarget("logconsole");

    // Rules for mapping loggers to targets            
    config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
    config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);

    // Apply config           
    NLog.LogManager.Configuration = config;
    LogManager.ReconfigExistingLoggers();
}

Затем, чтобы изменить уровень журнала, где logconsole является целью, которую вы хотите изменить:

public static void SetConsoleLogLevel(LogLevel level)
{
    foreach (var rule in LogManager.Configuration.LoggingRules)
    {
        foreach (var ruleTarget in rule.Targets)
        {
            if (ruleTarget != logconsole) continue;

            DisableLoggingForLevels(rule, LogLevel.Trace, level);
            rule.EnableLoggingForLevels(level, LogLevel.Fatal);
            LogManager.GetCurrentClassLogger().Log(level, "Changed logger level to {0}", level);
        }
    }

    LogManager.ReconfigExistingLoggers();
}

где DisableLoggingForLevels - это закрытый метод, такой же, как NLog.Config.LoggingRule.EnableLoggingForLevels за исключением того, что он отключает:

private static void DisableLoggingForLevels(LoggingRule rule, LogLevel minLevel, LogLevel maxLevel)
{
    for (var ordinal = minLevel.Ordinal; ordinal <= maxLevel.Ordinal; ++ordinal)
        rule.DisableLoggingForLevel(LogLevel.FromOrdinal(ordinal));
}

Ответ 4

Типичным способом перенастройки NLog во время работы приложения является использование файла конфигурации (например, NLog.config). Вы можете определить свою конфигурацию ведения журнала в файле, и вы можете указать NLog для просмотра файла. Если файл изменен (например, изменение уровня ведения журнала для одного или нескольких регистраторов), NLog перенастроит себя на основе содержимого файла.

Вы заявляете, что программно настраиваете NLog программно, поэтому полагаться на возможность перенастроить себя на основе изменения в файле конфигурации не является жизнеспособным решением.

Я мог бы пересмотреть свой вопрос примерно так:

В моем приложении у меня есть переменная-член, которую я инициализирую до 10 в конструкторе. Эта переменная-член контролирует, сколько раз мое приложение зацикливается до его завершения. Пока моя программа работает, я хотел бы изменить это значение, чтобы оно повторялось больше или меньше раз. Кто-нибудь знает, как я могу изменить переменную-член во время выполнения?

Проблема похожа на вашу. Как инициировать, извне, изменение вашего запущенного приложения? Я не думаю, что это специально для использования NLog.

Я думаю, что эту проблему трудно решить, если вы каким-то образом не измените свои настройки ведения журнала.

Если вы используете свой собственный файл конфигурации или другой файл, вы по существу дублируете то, что NLog уже делает с опцией своего файла конфигурации.

Если вы используете какой-то механизм опроса (возможно, периодически проверяйте какое-либо местоположение (файл, реестр,???)), а затем меняете конфигурацию NLog, если есть какой-то индикатор, который должен изменить конфигурацию NLog. храниться в этом месте? Новый уровень журнала? У вас есть только один регистратор для всего вашего приложения? Или у вас есть более типичный одиночный статический логгер для каждого класса? Если последний, вам нужна возможность указать, какой регистратор, который вы хотите изменить, и что изменить уровень.

Возможно, вы могли напрямую общаться с вашим приложением через какое-то общее состояние или межпроцессное общение. Похоже на большую работу.

Вполне возможно, что я не понимаю, что вы пытаетесь сделать, и что там действительно есть простой способ сделать это.

Как правило, я бы сказал, что есть два способа использования NLog, каждый из которых имеет преимущества и недостатки:

Файл конфигурации

  • Преимущества

    Прост в использовании.

    Очень мало кода, специфичного для NLog, в вашем приложении.

    Конфигурация регистрации может быть изменена во время работы приложения.

  • Недостатки

    Должно идти в ногу с конфигурационным файлом.

    Возможно, вы не захотите, чтобы кто-либо еще мог обманывать ваш журнал.

Конфигурировать программно

  • Преимущества

    Не нужно идти в ногу с конфигурационным файлом.

    Другие люди не могут легко обманывать ваш журнал.

  • Недостатки

    В вашем приложении больше кода, специфичного для NLog.

    Невозможно изменить свою конфигурацию NLog, пока ваше приложение работает с некоторым изобретением с вашей стороны.

    На самом деле, нельзя изменить конфигурацию NLog после того, как ваше приложение было скомпилировано без изменения исходного кода и перекомпиляции.

Я не знаю, помогло ли это вообще...