Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force reload of NLog configuration file?

I'm using NLog with configuration files. To avoid to log too much things for some long treatments, I'm doing this kind of thing :

 foreach (LoggingRule rule in LogManager.Configuration.LoggingRules) 
 {
      rule.DisableLoggingForLevel(LogLevel.Trace);   
      rule.DisableLoggingForLevel(LogLevel.Debug);   
 }
 LogManager.ReconfigExistingLoggers();

It allows me to temporarily degrade logging detail level. The lines above are just an example to illustrate. This seems to work perfectly.

After that, I would like to restore my "regular" logging configuration, simply by reloading my NLog.Config file which was already automatically loaded at program startup. I've tried :

LogManager.Configuration.Reload();
LogManager.ReconfigExistingLoggers();

I thought it would be easy but configuration.Reload doesn't do what I was expecting and I didn't find any other suitable method. After the call my logger still not store traces and debug events, while they were at program startup.

So my question is : how to programmatically force the reloading of NLog.config at runtime and restore my "standard" loggers settings ?

Thanks

Question update with more details :

I'm using VS2013, .Net 4 projet with NLog 4.4.0-beta11 (beta but last on nuget), simple "File" target defined in configuration file with minLevel = Trace and autoReload=True

Logger instantiated at class level : private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

Here's my test evidence :

    Assert.True(Logger.IsTraceEnabled);
    Assert.True(Logger.IsDebugEnabled);

    Logger.Trace("1 - This should appear in log");
    Logger.Debug("2 - This should appear in log");

    foreach (LoggingRule rule in LogManager.Configuration.LoggingRules)
    {
        rule.DisableLoggingForLevel(LogLevel.Trace);
        rule.DisableLoggingForLevel(LogLevel.Debug);
    }
    LogManager.ReconfigExistingLoggers();

    Logger.Trace("3 - This should NOT appear in log");
    Logger.Debug("4 - This should NOT appear in log");
    Logger.Info("5 - This should appear in log");

    Assert.False(Logger.IsDebugEnabled);
    Assert.False(Logger.IsTraceEnabled);

    LogManager.Configuration.Reload();
    LogManager.ReconfigExistingLoggers();

    // This is were something goes wrong

    Logger.Trace("6 - This should appear in log"); // DOES NOTHING
    Logger.Debug("7 - This should appear in log"); // DOES NOTHING
    Logger.Info("8 - This should appear in log");

    Assert.True(Logger.IsDebugEnabled); // FAILS
    Assert.True(Logger.IsTraceEnabled); // FAILS

Generated log :

    TRACE 1 - This should appear in log         
    DEBUG 2 - This should appear in log
    INFO 5 - This should appear in log
    INFO 8 - This should appear in log

In the nlog internal log I can see the configuration seems to have been reloaded with no problem (very long file so I don't post it here unless somebody asks), but maybe the existing loggers are not updated ?

With the code above it should be easy to try on your side. Please let me know if I do something wrong or if it's a bug inside NLog configuration management.

like image 578
AFract Avatar asked Jun 07 '16 19:06

AFract


1 Answers

Actually, you've got an error in your code: LogManager.Configuration.Reload() does not change configuration of logger, but loads configuration from NLog.config file, deserializes it and returns LoggingConfiguration as a result.

to restore configuration, you need to do something like this:

LogManager.Configuration = LogManager.Configuration.Reload();
LogManager.ReconfigExistingLoggers();

here is a test example (minLevel in example config = "DEBUG"):

[TestMethod]
        public void Test()
        {
            Logger.Trace("TRACE 1");
            Logger.Debug("DEBUG 1");
            Logger.Warn("WARN 1");

            foreach (LoggingRule rule in LogManager.Configuration.LoggingRules)
            {
                rule.DisableLoggingForLevel(LogLevel.Trace);
                rule.DisableLoggingForLevel(LogLevel.Debug);
            }
            LogManager.ReconfigExistingLoggers();

            Logger.Trace("TRACE 2");
            Logger.Debug("DEBUG 2");
            Logger.Warn("WARN 2");

            // Reconfigure();
            LogManager.Configuration = LogManager.Configuration.Reload();
            LogManager.ReconfigExistingLoggers();

            Logger.Trace("TRACE 3");
            Logger.Debug("DEBUG 3");
            Logger.Warn("WARN 3");
        }

output:

(DEBUG): DEBUG 1
(WARN): WARN 1
// here settings changed
(WARN): WARN 2
//here settings reloaded
(DEBUG): DEBUG 3
(WARN): WARN 3
like image 159
Johnny Svarog Avatar answered Oct 02 '22 18:10

Johnny Svarog