Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added NLog 4.6 is live post #99

Merged
merged 19 commits into from
Mar 20, 2019
Merged
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions _posts/2019-02-30-nlog-4-6-is-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
---
layout: post
title: NLog 4.6 is live!
---

NLog 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.

```xml
<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.
When using special DbType like `SqlDbType.SmallInt` then one can specify `parameterType="Int16"` to help.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is indeed important, but maybe it should be only in the wiki and not in the release post. (it is very much in-depth). Is that OK with you?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Think I was a little too happy about the change :)


This will skip the overhead of first rendering to string, and parsing the string into the expected type.

If wanting to use non-string DbType but want the value parsed from string, then one can do this: `${date:format=yyyy-MM-dd:norawvalue=true}` or specify `parameterType="String"`.

### NetworkTarget supports SSL & TLS
NetworkTarget can now perform SSL/TLS handshake for the TCP-protocol:

```xml
<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.

```xml
<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:

```xml
<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:

```xml
<parameter name="@props" dbType="SqlDbType.Xml">
<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.

```xml
<nlog>
<variable name='myLevel' value='debug'/>
<rules>
<logger minLevel='${myLevel}'/>
</rules>
</nlog>
```

Note: for performance reasons, ${var:myLevel} or other layout renderers won't work.

### 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

```xml
<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 <rule> element was limited.

- `?` 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

```xml
<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:

```xml
<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.

```xml
<target name="console" xsi:type="ColoredConsole" enableAnsiOutput="true" />
```

### AppSetting without NLog.Extended
NLog.Extended was needed when wanting to use `${appsetting}` on .NET Framework. But 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.

### NLog configuration inside appsettings.json
Copy link
Member

@304NotModified 304NotModified Mar 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snakefoot

We need to merge NLog/NLog.Extensions.Logging#263 first for this?

(and mention NLog.Extensions.Logging 1.5?) -

Doubting if this should be a separate post.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You decide. There is no law saying that the news-posts should be posted on the same day as the release is cut.

NLog LoggingConfiguration have always been highly configurable through XML. It is now also possible
to configure NLog to parse the configuration from other sources.

NLog.Extension.Logging is now able to load NLog LoggingConfiguration from Microsoft Extension ConfigurationSection.

This can be used for loading NLog-configuration from appsettings.json:

```c#
var config = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();

var nlogSection = config.GetSection("NLog");
LogManager.Configuration = new NLog.Extensions.Logging.ExtensionLoggingConfiguration(nlogSection);
```

```json
{
"NLog": {
"internalLogLevel": "Info",
"internalLogFile": "c:/temp/console-example-internal.log",
"throwConfigExceptions": "True",
"targets": {
"console": {
"type": "Console",
"layout": "${longdate}|${level:uppercase=true}|${logger}|${message}${exception:format=tostring}"
}
},
"rules": [
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "File,Console"
}
]
}
}
```

### LibLog Breaking change
[damianh/LibLog#181](https://github.com/damianh/LibLog/pull/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` or `OpenMappedContext`.

## Many other improvements

For a full list of all the enhancements and performance improvements: [NLog 4.6 Release Notes](https://github.com/NLog/NLog/blob/master/CHANGELOG.md)