reconfiguring NLog programmatically

筅森魡賤 提交于 2019-12-17 10:46:07

问题


This is my first time using the NLog package for logging but so far its been great to work with.

In my scenario I need to initialize my NLog LoggingConfiguration settings programmatically rather than thru the more typical config file scenario. I've tested this and got it all working the way I want it by default. But how would I go about modifying my settings programmatically at run-time? Probably the most common scenario here is one where the application's logging level is set to ERROR by default but a bug arises in a particular module that I want to switch the logging level to be much more verbose to track down the error. I'd like to write a little web interface so I can easily tweak these settings at runtime but I want to make sure I am taking the right approach with this.


回答1:


I know I'm a year late but I just ran into similar scenario where I needed to provide dynamic control of the logger to users. Fortunately, this is relatively easy with nlog. Here I'm just enabling Trace level logging to an already created Logger but obviously you could do anything you wanted including adding new Targets/Rules or just completely replace the LoggerConfiguration with your programmatically generated one.

Basic 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>

Simple console application:

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();
  }
}

If you need to alter the Logging configuration from outside the process and it has to be done programmatically, I would suggest going with WCF. You could expose a small WCF service from either your application or website that provides methods for reconfiguring nlog.




回答2:


I found "Configuration API" in NLog documentation (https://github.com/NLog/NLog/wiki/Configure-from-code), may be this help you. Look at NLog.Config namespace in NLog assembly too.

See also: https://github.com/NLog/NLog/wiki/Reinitialize-NLog-configuration




回答3:


A programmatic initial setup example is given on the NLog tutorial page here which I've included below. (There's a slightly more extensive version here.)

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();
}

Then, to change the log level, where logconsole is the target you want to change:

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();
}

where DisableLoggingForLevels is a private method exactly like NLog.Config.LoggingRule.EnableLoggingForLevels except that it disables:

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


来源:https://stackoverflow.com/questions/10302561/reconfiguring-nlog-programmatically

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!