1
votes

I'm trying to log messages with NLog to multiple targets, with multiple final rules.

Situation

NLog Version: 4.7.5
Plattform: .NET CORE 3.1
Config: XML File and configured programmatically

I have 2 targets File and Console

LogManager.Configuration.AddTarget(fileTarget);
LogManager.Configuration.AddTarget(consoleTarget);

And multiple rules like

new LoggingRule() {LoggerNamePattern = "A*",                           Target = fileTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot*",                       Target = fileTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of*",                    Target = fileTarget, MinLevel = Info,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical*",       Target = fileTarget, MinLevel = Info,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical.Rules*", Target = fileTarget, MinLevel = Debug, Final = true};

new LoggingRule() {LoggerNamePattern = "A*",                           Target = consoleTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot*",                       Target = consoleTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of*",                    Target = consoleTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical*",       Target = consoleTarget, MinLevel = Warn,  Final = true};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical.Rules*", Target = consoleTarget, MinLevel = Trace, Final = true};

I know that Target and MinLevel are no valid properties, but it's easier to show

The Rules must be final, otherwise all my log messages are duplicated.

EDIT: The users can change the LogLevel for each rule and for each target on runtime.

Problem

When I crate a new rule, I have to set the targets for this rule. When I add multiple targets to one rule, I get the message in each target but I can only define the LogLevel for both targets. And when I add the rule twice, with one target for each rule, then I get the messages only in the console and not in the file, because the final stops the other rules.

I've already checked the NLog Page, NLog GitHub and StackOverflow pages. All their problems are how to log to multiple targets, or log to multiple targets with different rules but only with one rule per target.

Expected

Define multiple final rules with different LogLevel for each Target

1

1 Answers

0
votes

Instead of grouping by target, then I suggest grouping them by logger-name-pattern, and have the most specific logger-name-pattern at the top:

new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical.Rules*", Target = fileTarget, MinLevel = Debug, Final = false};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical.Rules*", Target = consoleTarget, MinLevel = Trace, Final = true};

new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical*",       Target = consoleTarget, MinLevel = Warn,  Final = false};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of.Hierarchical*",       Target = fileTarget, MinLevel = Info,  Final = true};

new LoggingRule() {LoggerNamePattern = "A.Lot.Of*",                    Target = fileTarget, MinLevel = Info,  Final = false};
new LoggingRule() {LoggerNamePattern = "A.Lot.Of*",                    Target = consoleTarget, MinLevel = Warn,  Final = true};

new LoggingRule() {LoggerNamePattern = "A.Lot*",                       Target = fileTarget, MinLevel = Warn,  Final = false};
new LoggingRule() {LoggerNamePattern = "A.Lot*",                       Target = consoleTarget, MinLevel = Warn,  Final = true};

new LoggingRule() {LoggerNamePattern = "A*",                           Target = fileTarget, MinLevel = Warn,  Final = false};
new LoggingRule() {LoggerNamePattern = "A*",                           Target = consoleTarget, MinLevel = Warn,  Final = true};

new LoggingRule() {LoggerNamePattern = "*",                            Target = fileTarget, MinLevel = Warn,  Final = false};
new LoggingRule() {LoggerNamePattern = "*",                            Target = consoleTarget, MinLevel = Warn,  Final = false};

You can also create "blackhole" logging-rules without any targets. By setting minLevel = Trace and Final = true. Then any output matching the LoggerNamePattern will not flow down to any rules that might follow.

But maybe I'm misunderstanding the question. See also: https://github.com/nlog/NLog/wiki/Configuration-file#logger-name-filter