Home > Mobile >  Update to Nlog 5.0: Configuration not applied
Update to Nlog 5.0: Configuration not applied

Time:08-07

While upgrading from NLog 4.7.15 to 5.0.1 I found this test in our code base:

        [Test]
        public void CustomLogFactoryShouldBehaveCompletelyIndependent()
        {
            var memoryTarget4 = new MemoryTarget();
            memoryTarget4.Layout = "${level}|${logger}|${message}${exception}";
            var memoryTarget5 = new MemoryTarget();
            var customConfig = new LoggingConfiguration();
            customConfig.AddTarget("UnitTestLogger4", memoryTarget4);
            customConfig.LoggingRules.Add(new LoggingRule("UnitTestLogger4", LogLevel.Trace, memoryTarget4));
            customConfig.AddTarget("UnitTestLogger2", memoryTarget5);
            customConfig.LoggingRules.Add(new LoggingRule("UnitTestLogger2", LogLevel.Info, memoryTarget5));

            using (var customFactory = new LogFactory(customConfig)) // <<-- This ctor is marked obsolete
            {
                // Log logger defined only in custom config
                var logger4 = customFactory.GetLogger("UnitTestLogger4");
                logger4.Trace("Test4");
                Assert.That(memoryTarget4.Logs.Count, Is.EqualTo(1));
                Assert.That(memoryTarget5.Logs, Is.Empty);
                memoryTarget4.Logs.Clear();

               //... More cases tested here
           }
      }

The test works fine both in the old and the new version, but only after I disable the deprecation warning CS0618 for the constructor LogFactory(LoggingConfiguration).

To work around this, I tried to use the suggested alternative LoggingConfiguration(LogFactory), which connects the factory and the configuration basically the other way round.

        [Test]
        public void CustomLogFactoryShouldBehaveCompletelyIndependent()
        {
            var memoryTarget4 = new MemoryTarget();
            memoryTarget4.Layout = "${level}|${logger}|${message}${exception}";
            var memoryTarget5 = new MemoryTarget();

            using (var customFactory = new LogFactory())
            {
                var customConfig = new LoggingConfiguration(customFactory);
                customConfig.AddTarget("UnitTestLogger4", memoryTarget4);
                customConfig.LoggingRules.Add(new LoggingRule("UnitTestLogger4", LogLevel.Trace, memoryTarget4));
                customConfig.AddTarget("UnitTestLogger2", memoryTarget5);
                customConfig.LoggingRules.Add(new LoggingRule("UnitTestLogger2", LogLevel.Info, memoryTarget5));
                // customFactory.ReconfigExistingLoggers(); // <<-- Adding this changes nothing

                // Log logger defined only in custom config
                var logger4 = customFactory.GetLogger("UnitTestLogger4");
                logger4.Trace("Test4");
                Assert.That(memoryTarget4.Logs.Count, Is.EqualTo(1)); // <<-- Fails here, nothing was added to memoryTarget4.
                Assert.That(memoryTarget5.Logs, Is.Empty);
                memoryTarget4.Logs.Clear();
           }
      }

At least that's what I think should be changed. But the test fails now. The configuration is not applied, as the target does not get any logs.

What did I miss? What's the correct way of replacing the deprecated LogFactory(LoggingConfiguration) constructor here?

CodePudding user response:

The constructor new LogFactory(customConfig) became obsolete to ensure that the LoggingConfiguration.Factory-option had the expected value (Using the intended isolated LogFactory instead of the global static LogManager.Factory)

You can replace:

customFactory.ReconfigExistingLoggers();

With this so the configuration is activated:

customFactory.Configuration = customConfig;

Alternative you could do this:

using var customFactory = new NLog.LogFactory().Setup().LoadConfiguration(builder => {
   var memoryTarget4 = new MemoryTarget();
   memoryTarget4.Layout = "${level}|${logger}|${message}${exception}";
   var memoryTarget5 = new MemoryTarget();
   builder.Configuration.LoggingRules.Add(new LoggingRule("UnitTestLogger4", LogLevel.Trace, memoryTarget4));
   builder.Configuration.LoggingRules.Add(new LoggingRule("UnitTestLogger2", LogLevel.Info, memoryTarget5)));
}).LogFactory;

var logger4 = customFactory.GetLogger("UnitTestLogger4");
logger4.Trace("Test4");
Assert.That(memoryTarget4.Logs.Count, Is.EqualTo(1));
Assert.That(memoryTarget5.Logs, Is.Empty);
memoryTarget4.Logs.Clear();
  • Related