-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Filtering log messages
Log messages may be filtered via either routing or filtering.
Logging Rules is the most efficient way to perform filtering using the name of the Logger.
One can silence a noisy loggger by redirecting it to a "blackhole" by not specifying writeTo=
for the logging-rule. But if also needing custom filter logic, then one needs to use a Null target.
NLog 4.5 made it possible to specify empty
writeTo=""
, but when using older versions then Null target must be used.
<rules>
<!-- ignore events written that are written to a logger which starts with "Namespace." -->
<logger name="Namespace.*" minlevel="Trace" final="true" /> <!-- BlackHole that swallows everything -->
<logger name="Namespace.*" maxLevel="Info" final="true" /> <!-- BlackHole that swallows non-critical -->
</rules>
NLog v5 introduced the FinalMinLevel-option, because MaxLevel
was causing a lot of headache and confusion.
<rules>
<!-- ignore events written that are written to a logger which starts with "Namespace." -->
<logger name="Namespace.*" finalMinLevel="Off" /> <!-- BlackHole that swallows everything -->
<logger name="Namespace.*" finalMinLevel="Warn" /> <!-- BlackHole that swallows non-critical -->
</rules>
With the use of <filters>
then you can inspect the actual log-events and decide to ignore (blacklist) and/or allow (whitelist) the events. See also <when>
filter.
e.g.
<logger name="*" writeTo="file">
<filters defaultAction="Log">
<when condition="length('${message}') > 100" action="Ignore" />
</filters>
</logger>
The defaultAction
-option was introduced with NLog 4.6. Before NLog 5.0 then the default value was Neutral
.
Note filters gives a performance penalty, because NLog LogEventInfo objects will be allocated upfront even if discarded by filter-result.
The above configuration can be implemented directly in C# like this:
var config = LogManager.Configuration;
// some target
var fileTarget = new FileTarget();
// set-up rule with filter
var loggingRule = new LoggingRule("*", fileTarget);
loggingRule.FilterDefaultAction = FilterResult.Log;
loggingRule.Filters.Add(new ConditionBasedFilter()
{
Condition = "length('${message}') > 100",
Action = FilterResult.Ignore
});
config.LoggingRules.Add(loggingRule);
// apply config
LogManager.Configuration = config;
With NLog 5.0 then one can also do this:
NLog.LogManager.Setup().LoadConfiguration(builder => {
builder.ForLogger().FilterDynamicIgnore(evt => evt.FormattedMessage?.Length > 100).WriteToFile("log.txt");
});
LogManager.GlobalThreshold
can be assigned a LogLevel, and then only LogEvents with same severity (or higher) will be logged.
LogManager.GlobalThreshold
will overrule the configuration of logging rules. If logging rules says minLevel="Debug"
then LogManager.GlobalThreshold = LogLevel.Error
will still win.
if (IsProduction)
NLog.LogManager.GlobalThreshold = NLog.LogLevel.Info;
else
NLog.LogManager.GlobalThreshold = NLog.LogLevel.Trace; // No global filter
LogManager.CreateNullLogger()
will return a Logger-instance that will not generate any output.
This can be used to silence certain components without depending on the NLog-configuration.
var logger = IsProduction ? LogManager.CreateNullLogger() : LogManager.GetCurrentClassLogger();
logger.Info("No output when in production");
The .NET compiler has the ability to remove DEBUG-code when making Release-build. This means only Debug-build will give output, when using these conditional logging methods:
- Logger.ConditionalTrace - Performs logging using NLog
LogLevel.Trace
- Logger.ConditionalDebug - Performs logging using NLog
LogLevel.Debug
_logger.ConditionalDebug("DEBUG build only output");
It is shorthand of doing this:
#if DEBUG
_logger.Debug("DEBUG build only output");
#endif
Routing rules are more efficient than using dynamic filters, and the performance comes from static nature of the rules. NLog 4.6.7 introduced the ability to use Layout-logic for controlling LogLevel in the logging-rules, that can be explictly refreshed.
<nlog>
<variable name="myLevel" value="Warn" />
<rules>
<logger minLevel="${var:myLevel}" writeTo="file" />
</rules>
</nlog>
Then NLog 4.6.7 allows you to do this:
#if DEBUG
LogManager.Configuration.Variables["myLevel"] = "Debug";
LogManager.ReconfigExistingLoggers(); // Explicit refresh of Layouts and updates active Logger-objects
#endif
This could be used to create a special activate-debug-mode-method. After changing the loglevel-variable as shown above, then one could schedule a timer to restore default-level to "Warn" after 5 mins.
The Semi Dynamic Routing Rules improves the combination of NLog configuration loaded from config-file, and adjusting NLog configuration at runtime.
When NLog configuration is created at runtime alone, then one have access to even more dynamic filtering logic capabilities. Ex. by using NLog.Filters.WhenMethodFilter
:
config.LoggingRules.Last().Filters.Add(new WhenMethodFilter(logEvent => ShouldIgnoreLogEvent(logEvent) ? FilterResult.Ignore : FilterResult.Log));
It is also possible to use the NLog.Config.LoggingRule
constructor that specifies RuleName
. Where it is possible to lookup the LoggingRule using LoggingConfiguration.FindRuleByName
when needing to adjust it.
These filters are deprecated. They have been replace by the <when>
filter, which exposes uses modifiable conditions for filtering log events.
-
<whenContains>
filter - Matches when the calculated layout contains the specified substring. -
<whenEqual>
filter - Matches when the calculated layout is equal to the specified substring. -
<whenNotContains>
filter - Matches when the calculated layout does NOT contain the specified substring. -
<whenNotEqual>
filter - Matches when the calculated layout is NOT equal to the specified substring.
- Troubleshooting Guide - See available NLog Targets and Layouts: https://nlog-project.org/config
- Getting started
- How to use structured logging
- Troubleshooting
- FAQ
- Articles about NLog
-
All targets, layouts and layout renderers
Popular: - Using NLog with NLog.config
- Using NLog with appsettings.json