NLog 4.6 is live!
20 Mar 2019NLog 4.6 contains lots of new features and performance improvements.
Main features
DatabaseTarget supports parameter types
It is now possible to configure the type for the DatabaseTarget parameters. Instead of always sending string-value then one can write the actual value-type.
<target name="db" xsi:type="Database" connectionstring="..." >
<commandtext>INSERT INTO FooBar VALUES(@ts, @lvl, @msg)</commandtext>
<parameter name="@ts" layout="${date}" dbType="SqlDbType.DateTime2" />
<parameter name="@lvl" layout="${level}" dbType="DbType.Int32" />
<parameter name="@msg" layout="${message}" dbType="SqlDbType.VarChar" size="-1" parameterType="String" />
</target>
When using a non-string DbType then it will attempt to convert the raw value directly to the expected type.
NetworkTarget supports SSL & TLS
NetworkTarget can now perform SSL/TLS handshake for the TCP-protocol:
<target name="net" type="network" address="tcp://127.0.0.1" sslProtocols="Tls12" />
NetworkTarget has also received a new TCP option for activating KeepAliveTime. keepAliveTimeSeconds=”30” can be used to keep TCP connection going when no traffic (with very little overhead).
New XmlLayout
XmlLayout is now available for creating XML files.
Just like with JsonLayout then XmlLayout supports object reflection, so it can be used in combination with structured logging.
<layout xsi:type="XmlLayout" includeAllProperties="True" elementName='logevent'>
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level:upperCase=true}"/>
<element name="message" layout="${message}" />
</layout>
Will write:
<logevent time="2010-01-01 12:34:56.0000" level="ERROR">
<message>hello, world</message>
</logevent>
This can also be used together with the DatabaseTarget for writing XML to a database:
<parameter name="@props" dbType="SqlDbType.Xml" size="-1">
<layout type="xmllayout" includeAllProperties="true" />
</parameter>
Variables in level attributes
In the XML configuration you could now variables in the level attributes (minlevel, maxlevel, level and levels),
e.g.
<nlog>
<variable name='myLevel' value='debug'/>
<rules>
<logger minLevel='${myLevel}'/>
</rules>
</nlog>
NLog ver. 4.6.7 adds support for using ${var:myLevel}
or other layout renderers. Allowing one to update filters at runtime like this:
LogManager.Configuration.Variables["myLevel"] = "Debug";
LogManager.ReconfigExistingLoggers();
Added default action for filtering
Currently the default action for filtering - when not matching any rule - is “neutral”.
This is a bit tricky. This could be now configured with the attribute defaultAction. Possible values: Neutral, Ignore, Log, LogFinal, IgnoreFinal
<rules>
<logger name='*' level='Warn' writeTo='myTarget'>
<filters defaultAction='Ignore'>
<when condition="starts-with(message, 't')" action='Log' />
</filters>
</logger>
</rules>
In NLog 5 the default will be probably changed to “ignore”
Substring, left and right
New layout renders has been added:
${substring:${level}:start=2:length=2} // from index 2, length 2
${substring:${level}:start=-2:length=2} // from end -2, length 2
${left:${level}:length=2} // from start, length 2
${right:${level}:length=2} // from end, length 2
Name filter: support for multiple wildcards and in any position
In NLog 4.5 and before, the wildcards in the name filter of the
?
was not supported- Only one
*
was allowed the name filter.
With a new implementation, those restrictions are now gone and ?
wildcard has been added.
*
- matches 0 or more characters?
- matches exactly 1 character
Examples
<logger name="*.Library.*" minlevel="Warn" writeTo="f3" />
<logger name="*TcpTestServer[*].Connection[??].*" writeTo="logconsole" />
InternalLogFile variables
The internalLogFile attribute is for stability limited in features, no layout renderers where allowed.
In NLog 4.6 we added support for: ${currentdir}, ${basedir} & ${tempdir}, and for environment variables, like %myPath%
example:
<nlog internalLogFile="${basedir}\log.txt" internalLogLevel="Trace">
<targets>
<!-- target configuration here -->
</targets>
<rules>
<!-- log routing rules -->
</rules>
</nlog>
AsyncWrapper uses ConcurrentQueue
ConcurrentQueue has been optimized with .NET Standard 2.0, so it provides high performance and little allocation.
NLog AsyncWrapper will now automatically make use of ConcurrentQueue when running on .NET Core 2 platform. This will greatly reduce the congestion overhead of having multiple threads writing to the same AsyncWrapper.
AsyncWrapper with faster timer
AsyncWrapper no longer schedules a timer every 50 ms even if nothing to write. Instead, it will schedule a single timer on first write and the timer will trigger after 1 ms.
This allows the AsyncWrapper to handle high loads out of the box, but will also make it more aggressive on the target it is wrapping. Instead of writing 40000 msgs/sec then it will handle 400000 msgs/sec.
ColoredConsoleTarget supports Ansi output
Console coloring now also works on VS Code or other console terminal using ANSI color escape sequences.
<target name="console" xsi:type="ColoredConsole" enableAnsiOutput="true" />
AppSetting without NLog.Extended
NLog.Extended was needed when wanting to use ${appsetting}
on .NET Framework. However it also had
dependencies on System.Messaging (MSMQ). Since NLog already dependends on System.Configuration
then it didn’t make sense also to need NLog.Extended for reading app.config / web.config.
Snupkg
The new releases will also publish a snupkg to nuget.org, for improved package debugging experience. See also the NuGet blog
LibLog Breaking change
damianh/LibLog#181 - Sub-components using LibLog ver. 5.0.3 (or newer) will now use MDLC + NDLC (Instead of MDC + NDC) when detecting application is using NLog ver. 4.6.
- Make sure to update NLog.config to match this change.
- Make sure that all sub-components have upgraded to LibLog ver. 5.0.3 (or newer) if they make use of
OpenNestedContext
orOpenMappedContext
.
Many other improvements
For a full list of all the enhancements and performance improvements: NLog 4.6 Release Notes
Happy logging!