7
votes

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.

1
This is the correct way to use it. Check the internal log, it will tell what happens while reloading.Julian
Hello. Good to know. Tomorrow I'll enable Nlog internal log with max details and keep you informed. Thank youAFract
Hello @Julian. I've posted above exactly the test I did and still have the issue. Could you please check it ? Thank you very much if like I think you are one of the main authors of NLog, i'm using it with great pleasure for almost all of my projects since many years.AFract
Johnny Svarog gave the reply. I feel a bit stupid to don't have noticed a so simple thing :)AFract

1 Answers

8
votes

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