NLog logging
Log writing
class Program
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
static void Main()
{
var x = 1;
Logger.Warn("Danger, Will Robinson!");
Logger.Error("Danger, {0}!", x);
try
{
throw new InvalidOperationException("Oops");
}
catch (InvalidOperationException ex)
{
Logger.Error(ex, "Exception logged");
}
}
}
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
static void Main()
{
var x = 1;
Logger.Warn("Danger, Will Robinson!");
Logger.Error("Danger, {0}!", x);
try
{
throw new InvalidOperationException("Oops");
}
catch (InvalidOperationException ex)
{
Logger.Error(ex, "Exception logged");
}
}
}
Logging Traces
Many libraries log to Trace:
System.Diagnostics.Trace.TraceWarning("Danger!");
It's nice not to take a dependency on logging when people have different preferences.
NLog includes a trace listener, so just hook it up in web/app.config
<configuration>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="MyNLogTraceListener" type="NLog.NLogTraceListener, NLog" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="MyNLogTraceListener" type="NLog.NLogTraceListener, NLog" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
The only limitation is the layout ${logger} symbol is just the executing assembly, not the class where logging occurred. Not a great problem, as you may be more specific in your ${message}: Trace.TraceInformation("Runner.Run started")
NLog.config
You can configure in the app/web.config but creating a NLog.config is the most common strategy.
Simple
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target name="logfile"
xsi:type="File"
fileName="../logs/file.txt"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
/>
</targets>
<rules>
<!-- Minimal level of Warn (not Trace, Debug, Info, just Warn, Error and Fatal) to "log"-->
<logger name="*" minlevel="Warn" writeTo="logfile" />
</rules>
</nlog>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target name="logfile"
xsi:type="File"
fileName="../logs/file.txt"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
/>
</targets>
<rules>
<!-- Minimal level of Warn (not Trace, Debug, Info, just Warn, Error and Fatal) to "log"-->
<logger name="*" minlevel="Warn" writeTo="logfile" />
</rules>
</nlog>
- autoReload="true" - changing the file will immediately reload this config
- <logger takes all sources (*) with a minimum level (order: Trace, Debug, Info, Warn, Error, Fatal) and sends them to named logger.
- <target is xsi:type="File" (as opposed to console or email etc)
- layout contains $() tokens. For date/time, ${longdate} seems best. It's useful to have ${message} AND ${exception:format=tostring} if you log an exception object
Multiple rules and targets
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target name="console" xsi:type="Console" />
<target name="testconsolefile" xsi:type="File" fileName="testconsolefile.txt" />
<target name="logfile"
xsi:type="File"
fileName="../logs/file.txt"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
/>
</targets>
<rules>
<logger name="*" minlevel="Warn" writeTo="logfile" />
<!-- Log specific component to special log -->
<logger name="TestConsole.*" minlevel="Debug" writeTo="testconsolefile" />
</rules>
</nlog>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets>
<target name="console" xsi:type="Console" />
<target name="testconsolefile" xsi:type="File" fileName="testconsolefile.txt" />
<target name="logfile"
xsi:type="File"
fileName="../logs/file.txt"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
/>
</targets>
<rules>
<logger name="*" minlevel="Warn" writeTo="logfile" />
<!-- Log specific component to special log -->
<logger name="TestConsole.*" minlevel="Debug" writeTo="testconsolefile" />
</rules>
</nlog>
Rolling Files
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets async="true">
<target name="logfile"
xsi:type="File"
fileName="../logs/file.log"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
archiveFileName="../logs/file.{#}.log"
archiveEvery="Day"
archiveNumbering="Sequence"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="14"
/>
</targets>
<rules>
<logger name="*" minlevel="Warn" writeTo="logfile" />
</rules>
</nlog>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true">
<targets async="true">
<target name="logfile"
xsi:type="File"
fileName="../logs/file.log"
layout="${longdate} ${pad:padding=5:inner=${level}} ${logger} ${message} ${exception:format=tostring}"
archiveFileName="../logs/file.{#}.log"
archiveEvery="Day"
archiveNumbering="Sequence"
archiveDateFormat="yyyyMMdd"
maxArchiveFiles="14"
/>
</targets>
<rules>
<logger name="*" minlevel="Warn" writeTo="logfile" />
</rules>
</nlog>
- <targets async="true"> creates an "AsyncWrapper" implicitly, so log writes are async and buffered.
- Like the log4net's RollingFileAppender
- By size:- archiveAboveSize="1048576" = 1Mb
- By time:- archiveEvery="Day"
- archiveNumbering="Sequence" or Date or DateAndSequence
- Rolling over is slow
- maxArchiveFiles is default 9