Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Logging setup in 5 minutes with NLog

, 13 Oct 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Logging is so important in any live application.

The time has come where I needed to add some sophisticated logging to Directory Monitor. I know there are a couple of frameworks out there and this comparison chart lays it out quite nicely although it may be quite dated. So after some quick investigation on the free ones I decided to go with NLog.

  • ObjectGuy Framework was really appealing at only a 40KB dependency. It's really simple and actually quite powerful, I chose not to use it because as you can see in the chart, thread safety is questionable (not sure why or hasn’t been tested) and it doesn't have built in file rotation/archiving. - @Lorne set me straight, the  ObjectGuy Framework does indeed have these features, however, my decision still stands for reasons beyond this.
  • Log4Net is a good option but the license didn’t agree with me because I want to use it for closed source applications.
  • Enterprise Library is a monster with lots of other dependencies, really only for large scale applications and if you want to extend it to do crazy things. Use it at work almost exclusively but not ideal for my small app.
  • NLog is 372KB, works in Mono (enterprise library as well), and has a build for WP7, all versions of the framework, Silverlight etc. Because of this I didn't mind checking it out because it immediately allows me to take that learning anywhere, to almost any application I build. There is also a great monitoring tools you can use along with it such as Sentinel or Harvester.

Quick Setup

You can download and install it or just add it through NuGet in Visual Studio.

Configuration File

Just make a config called NLog.config in the root of your project.

When editing the configuration file, reference the XSD and you'll get intellisense and inline comments in Visual Studio: Right-click the config -> Properties -> Schemas -> "C:\Program Files (x86)\Microsoft Visual Studio 10.0\xml\Schemas\NLog.xsd"

If you have a separate config file, make sure you set the "Copy to Output Directory" is set to "Copy Always" to avoid many tears wondering why the logging doesn't work.

CopyToOutputDirectory

You get a lot of layout options to play with, this is my configuration file, it writes to the event log on error and fatal, creates a daily rolling log file (30 days max), everything is asynchronous and the configuration auto reloads on the fly if anything changes. It also writes to a location that you will have write access to in low privilege situations.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="false">

  <variable name="appName" value="YourAppName" />
  
  <targets async="true">
    <target xsi:type="File"
            name="default"            
            layout="${longdate} - ${level:uppercase=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
            fileName="${specialfolder:ApplicationData}\${appName}\Debug.log"
            keepFileOpen="false"
            archiveFileName="${specialfolder:ApplicationData}\${appName}\Debug_${shortdate}.{##}.log"
            archiveNumbering="Sequence"
            archiveEvery="Day"
            maxArchiveFiles="30"
            />
    
    <target xsi:type="EventLog"
            name="eventlog"
            source="${appName}"
            layout="${message}${newline}${exception:format=ToString}"/>
  </targets>
  <rules>
    <logger name="*" writeTo="default" minlevel="Info" />
    <logger name="*" writeTo="eventlog" minlevel="Error" />
  </rules>
</nlog>

Code

This is the singleton class that I use which also includes targets for Sentinel and Harvester when I'm running a debug build.

using NLog;
using NLog.Config;
using NLog.Targets;

namespace YourAppName.Logging
{
  internal static class Log
  {
    public static Logger Instance { get; private set; }
    static Log()
    {
#if DEBUG
      // Setup the logging view for Sentinel - http://sentinel.codeplex.com
      var sentinalTarget = new NLogViewerTarget()
      {
        Name = "sentinal",
        Address = "udp://127.0.0.1:9999"
      };
      var sentinalRule = new LoggingRule("*", LogLevel.Trace, sentinalTarget);
      LogManager.Configuration.AddTarget("sentinal", sentinalTarget);
      LogManager.Configuration.LoggingRules.Add(sentinalRule);

      // Setup the logging view for Harvester - http://harvester.codeplex.com
      var harvesterTarget = new OutputDebugStringTarget()
      { 
        Name = "harvester",
        Layout = new Log4JXmlEventLayout()
      };
      var harvesterRule = new LoggingRule("*", LogLevel.Trace, harvesterTarget);
      LogManager.Configuration.AddTarget("harvester", harvesterTarget);
      LogManager.Configuration.LoggingRules.Add(harvesterRule);
#endif

      LogManager.ReconfigExistingLoggers();

      Instance = LogManager.GetCurrentClassLogger();
    }
  }
}

Monitoring Tools

Let Sentinel or Harvester run all the time when you are debugging and it will pick up everything that your app is logging (screenshots from their respective project pages).

Sentinel

Harvester

Start Logging

Now to start log anything, anywhere in your app, just use the static log instance.

try
{
  Log.Instance.Debug("We're going to throw an exception now.");
  Log.Instance.Warn("It's gonna happen!!");
  throw new ApplicationException();
}
catch (ApplicationException ae)
{
  Log.Instance.ErrorException("Error doing something...", ae);
}

This is a really simple and effective setup but you can of course get really advanced from there, all in the configuration file.

The cool thing about having a separate log file is that you can send someone a modified log file that will write trace level logging or even ship the log to a web server or database for you to check out.

Logging is so important in any live application. This just makes it easy while still leaving it very powerful if you ever need to use that power. The logger itself is pretty easy to debug because of it's massive internal logging and setting to expose the internals of it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Werner van Deventer
Software Developer (Senior)
South Africa South Africa
No Biography provided
Follow on   Twitter   Google+

Comments and Discussions

 
QuestionBetter comparison table PinmemberJoao Teixeira Soares29-Oct-12 1:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 14 Oct 2012
Article Copyright 2012 by Werner van Deventer
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid