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