8

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.

AFract
  • 8,868
  • 6
  • 48
  • 70
  • 1
    This is the correct way to use it. Check the internal log, it will tell what happens while reloading. – Julian Jun 07 '16 at 20:07
  • Hello. Good to know. Tomorrow I'll enable Nlog internal log with max details and keep you informed. Thank you – AFract Jun 07 '16 at 20:14
  • 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 Jun 08 '16 at 07:49
  • Johnny Svarog gave the reply. I feel a bit stupid to don't have noticed a so simple thing :) – AFract Jun 08 '16 at 08:56

1 Answers1

9

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
Johnny Svarog
  • 1,125
  • 10
  • 17
  • Hello, you're absolutely right, I did the change and it's ok now. Sorry, I didn't noticed Configuration.Reload() was a pure method just returning the defined settings, I thought its purpose was to reload and apply the configuration. – AFract Jun 08 '16 at 08:54
  • 2
    Hi, yes, it seems as if it should work this way indeed, but actually it doesn't... I would rename this method to 'Load' if I were a developer from NLog team =) – Johnny Svarog Jun 08 '16 at 09:00
  • 2
    Then this: NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(NLogConfigFile_Dst, true); NLog.LogManager.ReconfigExistingLoggers(); should do the same thing... load the configuration from the file and then reconfigure the loggers - right? – MrLister May 01 '17 at 22:03