What it is
NLog is a flexible .NET logging platform with rich routing rules, many targets and configuration that can be changed without recompiling.
Targets define destinations, rules route loggers by name and level to targets. Configuration is XML or code, and can reload on change.
Installation
dotnet add package NLog.Web.AspNetCoreGetting started
The smallest useful thing you can do with it, and what each part means.
<nlog autoReload="true" throwConfigExceptions="true">
<targets>
<target name="file" xsi:type="File"
fileName="logs/${shortdate}.log"
archiveEvery="Day" maxArchiveFiles="14" />
<target name="json" xsi:type="File" fileName="logs/app.json">
<layout xsi:type="JsonLayout" includeEventProperties="true" />
</target>
</targets>
<rules>
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="*" minlevel="Info" writeTo="file,json" />
</rules>
</nlog>Advanced usage
Where the library earns its place over a simpler alternative.
csharp
// Named holes, as with Serilog — not interpolation.
_logger.LogInformation("Order {OrderId} shipped to {Customer}",
order.Id, order.Customer);
using (_logger.BeginScope(new Dictionary<string, object>
{
["CorrelationId"] = correlationId,
}))
{
_logger.LogInformation("processing"); // carries CorrelationId
}
// Wrap slow targets so logging never blocks the request thread.
<target name="asyncFile" xsi:type="AsyncWrapper" queueLimit="5000"
overflowAction="Discard">
<target xsi:type="File" fileName="logs/app.log" />
</target>Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- No log output at all
- Set throwConfigExceptions="true" and internalLogFile to see why the configuration failed to load — a bad target usually fails silently otherwise.
- Log entries are lost under load
- The async queue overflowed. Raise queueLimit or change overflowAction to Block if losing entries is unacceptable.
Best practices
- Use message templates with named holes, never string interpolation.
- Wrap file and network targets in AsyncWrapper so logging does not block requests.
- Filter framework namespaces with a final rule to cut noise at the source.
- Call LogManager.Shutdown() on exit so buffered entries are flushed.
Background
Why it exists, and what it was reacting to.
NLog predates structured logging and remains popular where operations teams need to change logging behaviour by editing a configuration file on a running system.
