NLog and Castle Logging Facility for Logging

One of the most important features of any application is a good logging strategy. Because of this, Highway.OnRamp.MVC.Logging brings together two very well established projects to provide a world class logging experience. First, we use the Castle Logging Facility to provide a common abstraction over logging, so you are not coupled to a specific logging framework. Then we implement NLog to perform the actual logging, configuring it via the NLog.config file.

How do I log from a class?

If you want to log from a class, there is a very simply pattern we recommend you follow:

1
2
3
4
5
6
7
8
9
10
11
using Castle.Core.Logging;

public class MyNewClass
{
  public MyNewClass()
  {
      Logger = NullLogger.Instance;
  }
  
  public ILogger Logger { get; set; }
}

The steps are quite simple:

  • Declare a public property of type ILogger
  • Initialize that property in your constructor to NullLogger.Instance

This uses the ability of Castle.Windsor to do Property injection, so that after you class is constructed Castle Windsor will assign the real logger to that Logger property. But, if you ever remove the LoggingInstaller your code will continue to work because the NullLogger is a proper implementation of ILogger which does nothing. This avoids NullReferenceExceptions when you don’t have a Logger injected, for instance during tests.

How does that get setup to begin with?

The Logging Facility is setup in the LoggingInstaller class, where we configure it. A facility is a Castle.Windsor concept for a bundled set of registrations and behaviors. As you can see, this makes properly configuring something like NLog very easy:

1
2
3
4
5
6
7
8
public class LoggingInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {

        container.AddFacility<LoggingFacility>(m => m.UseNLog().WithConfig("NLog.config"));
    }
}

That really is all there is to it, we configure the facility to use NLog, and then tell it where the config file is. Now, the config file we include is very simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      globalThreshold="Debug">

  <targets>
    <target xsi:type="File"
            name="file"
            fileName="${basedir}/Logs/Log.txt"
            archiveEvery="Day" />
  </targets>

  <rules>
    <logger name="*" minlevel="Debug" writeTo="file" />
  </rules>
</nlog>

This configuration sets up a Logs directory that will contain Log.txt as a file which will be archived to another file every day. It also configures NLog to log all messages Debug and above by default. Not that while NLog supports a Trace level, below Debug, Castle Logging Facility does not so this essentially says “log everything to Logs.txt”. There is a great deal more that can be done with NLog and I encourage you to review their documentation on config.

What is logged automatically for me?

We setup two types of loggers for you automatically;

  • The App_Start component LoggerAnnouncementsWireup logs a message every time your application starts up, and if it properly shuts down.
  • The filter ExceptionLoggingFilter logs every exception that is unhandled by the application.

Comments