An NLog target that writes events to Seq. The target takes full advantage of the structured logging support in NLog 4.5 to provide hassle-free filtering, searching and analysis.
After installing NLog, install the NLog.Targets.Seq package from NuGet:
dotnet add package NLog.Targets.Seq
Then, add the target and rules entries to your NLog configuration:
<nlog>
<extensions>
<add assembly="NLog.Targets.Seq"/>
</extensions>
<targets>
<target name="seq" xsi:type="BufferingWrapper" bufferSize="1000"
flushTimeout="2000" slidingTimeout="false">
<target xsi:type="Seq" serverUrl="http://localhost:5341" apiKey="" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="seq" />
</rules>
</nlog>
The BufferingWrapper
ensures that writes to Seq do not block the application.
Set the serverUrl
value to the address of your Seq server, and provide an API key if you have one set up.
A complete sample application and NLog.config file can be found here in this repository.
NLog 4.5 adds support for message templates, extended format strings that capture first-class properties along with the usual message text.
var logger = LogManager.GetCurrentClassLogger();
for (var i = 0; i < 10; ++i)
{
logger.Info("Hello, {Name}, on iteration {Counter}", Environment.UserName, i);
}
When the events logged in this snippet are rendered to a file or console, they'll appear just like regular formatted text. In Seq or another structured log data store, you'll see that the original Name
and Counter
values are preserved separately:
This makes filtering with expressions such as Counter > 8
or Name like 'nb%'
trivial: no regular expressions or log parsing are needed to recover the original values.
The fully-rendered message is there too, so you can still search for text like "Hello, nblumhardt"
and find the events you'd expect.
The target
declaration in NLog.config can be expanded with additional properties:
<target xsi:type="Seq" serverUrl="http://localhost:5341" apiKey="">
<property name="ThreadId" value="${threadid}" as="number" />
<property name="MachineName" value="${machinename}" />
<property name="Source" value="${logger}" />
</target>
Any properties specified here will be attached to all outgoing events. You can see examples of ThreadId
and MachineName
in the screenshot above. The value can be any supported layout renderer.
NLog.Extensions.Logging ver. 1.5.0 adds support for having NLog configuration in appsettings.json
{
"NLog": {
"throwConfigExceptions": true,
"extensions": [
{ "assembly": "NLog.Targets.Seq" }
],
"targets": {
"seq": {
"type": "BufferingWrapper",
"bufferSize": 200,
"flushTimeout": 2000,
"slidingTimeout": false,
"target": {
"type": "Seq",
"serverUrl": "http://localhost:5341",
"apiKey": "",
"properties": [
{
"name": "Source",
"value": "${Logger}"
},
{
"name": "ThreadId",
"value": "${ThreadId}",
"as": "number"
},
{
"name": "MachineName",
"value": "${MachineName}"
}]
}
}
},
"rules": [
{
"logger": "*",
"minLevel": "Info",
"writeTo": "seq"
}]
}
}
The target is based on the earlier Seq.Client.NLog project, and benefits from many contributions accepted into that repository.