Using NLog to provide custom tracing for your ASP.NET Web API

One of the things I love most about MVC3, and now ASP.NET Web API, is that pretty much any functionality or service that is used by your application, can be replaced with a custom one. One of these is the entire tracing mechanism that Web API uses.

Let’s have a look today at how you can build a simple System.Web.Http.Tracing.ITraceWriter implementation to provide support for a custom logging framework in your Web API – in our case it will be NLog.

More after the jump.

What is NLog?

Well, if you don’t know your are probably on a wrong blog 🙂 – but in short, NLog is a free open source logging framework for .NET (official site here), started by Microsoft’s Jarek Kowalski. It is extremely powerful, and very easy to setup. And it also happens to be my favorite one, that’s why I am going to use it here today.

With NLog you can easily write debug info to:
– files
– event log
– database
– network
– email
– command line console
– and many other providers

Why do we even need this and how to start?

A good question is why would you even need to do something? Wouldn’t using System.Diagnostics.Trace in your code enough?

Well, depends on how you look at it. In simple cases probably yes, but with plugging your own logging framework to ASP.NET Web API you get 2 major advantages:
– you can leverage on all the functionalities offered by NLog, like the above mentioned logging providers and easily log to different targets
– you channel all the internal ASP.NET Web API tracing to your provider as well. This means you can easily keep track of the traces that were put in by MSFT team and use those to debug/optimize your applications.

In order to plug your own trace provider to ASP.NET Web API you need a class that derives from System.Web.Http.Tracing.ITraceWriter.

In Web API RC the interface requires us to implement an additional method IsEnabled(). This is going to be obsolete in full release, as this method has been removed from the interface on May 15 in this commit. Therefore, since this code is written against RC, we will explicitly implement it but not use it for anything.

Our sample implementation

Let’s build a sample implementation. You can use any dummy Web API project for that – I just happen to have a redundant EF Code first/Ninject project, but that doesn’t really matter.

We need to start off by grabbing nLog from Nuget.

Next, we need to configure nLog in web.config. In the “configSections” add:

And directly under “configuration”, add:

In this example we will use logging to a file and logging to event viewer, but obviously you are free to leverage on any of the powerful features of nLog. Note that I added ${basedir} in the file path – that is required to tell nLog that the file needs to be created under the web application’s root folder; otherwise it wouldn’t know where to put the file and no log file would be created.

We set the minimum log level to “Trace” – so that we are as verbose as possible, and log everything.

Now, we need a class implementing ITraceWriter:

So, whenever the Trace() method would be invoked, we check if logging is on, build an instance of System.Web.Http.Tracing.TraceRecord, invoke a delegate (if passed) and call our private Log method, where we will introduce nLog logging.

The above mentioned delagates are used by internal Web API tracers from the System.Web.Http.Tracing.Tracers namespace. In our example we will use shorthand extensions from the static System.Web.Tracing.ITraceWriterExtensions, so we won’t explicitly pass any delegates to our ITraceWriter.

Notice that I also introduced a private Dictionary which will serve us as mapping between Web API’s System.Web.Http.Tracing.TraceLevel enum and nLog logging level methods.

Let’s look at the Log method:

This is a very simple method; depending on whether the “Operator” and “Exception” properties are set the message is more or less detailed. Then we invoke the appropriate nLog method to log the information.

Final step is to add our implmentation of ITraceWriter to GlobalConfigurarion. A side note – if you are using dependency injection, i.e. Ninject, and want to have logging available already there, you need to add the line below just at application start – and since DI frameworks usually use web activator, it would have to be somehwere under App_start folder.

Adding logging to our application

Now let’s add logging to several places in our application.

We can add some elsewhere, i.e. in Ninject resolver and Global.asax:

A note here – since the ITraceWriter requires an instance of HttpRequestMessage to be explicitly passed to the Trace method, we cheat a little, and pass an empty one in the places where it is not available (i.e. Global.asax).

Now let’s run the application, play around a little bit and see the log messages piling up. Since we set a very verbose trace level, you can see lots of helpful information coming from the internal Web API tracers.

The event viewer is also logging everything as it should:

One last thing worth mentioning, is that you can go even a step further, and instead of implementing a custom ITraceWriter you might implement an entirely own System.Web.Http.Tracing.ITraceManager. You’d then get the maximum control over anything that Web API does; however you’d have to effectively replace or rewrite everything that’s located under System.Web.Http.Tracing.Tracers – so all Web API’s internal tracers.


As most of the Web API stuff, plugging in your custom logging framework is very easy and smooth. With that in hand, you get very granular control over your tracing and debugging mechanisms and can leverage on the powerful features of your favorite logging framework – like I used nLog in this case.

Till next time!