Adding NLog to your Azure Mobile Service instance

What is NLog?

NLog is a .NET logging framework that was originally created by one of my former co-workers, Jarek Kowalski.

Setup

Install NLog, NLog.Schema, and NLog.Config from NuGet using the package manager console in Visual Studio. Be sure to select the correct default project.

    Install-Package NLog
    Install-Package NLog.Config
    Install-Package NLog.Schema

Add your targets!

Let's add two targets: Console and Azure Table Storage. We can add NLog targets either through the NLog.config or programmatically. I'm going to show you both so that we cover all the bases.

Console Target (via NLog.config)

In the NLog.config, add a console target and rule. It should look something like this:

<?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"
      throwExceptions="true">

  <targets>
    <!-- console target -->
    <target name="console" xsi:type="Console" layout="${longdate} ${callsite} ${level} ${message}"/>
  </targets>

  <rules>
    <!-- console logging rule -->
    <logger name="*" minlevel="Trace" writeTo="console"/>
  </rules>
</nlog>

Double check that the file properties of the NLog.config is set to Copy to Output Directory = Copy Always.

Azure Table Storage Target (programmatically)

  1. Install the package via NuGet: Install-Package AzureTableStorageNLogTarget.
  2. This is where we need to do special work for Azure Mobile Service. Usually this would live within Application_Start of Global.asax, but for our Azure Mobile Service, we need to add this in the Register function of WebApiConfig.cs.
public static class WebApiConfig  
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public static void Register()
    {
        // Setup NLog
        var loggingConfig = new LoggingConfiguration();

        // Add Azure Table Target
        var azureTableStorageTarget = new AzureTableStorageTarget
        {
            ConnectionString = [[AZURE_STORAGE_CXN_STRING]],
            TableName = [[LOG_TABLE_NAME]],
        };

        loggingConfig.AddTarget("AzureTableStorage", azureTableStorageTarget);

        var rule = new LoggingRule("*", LogLevel.Trace, azureTableStorageTarget);
        loggingConfig.LoggingRules.Add(rule);

        LogManager.Configuration = loggingConfig;
        LogManager.ReconfigExistingLoggers();

        Logger.Info("[Register] Done");
        LogManager.Flush();
    }
}

Vroom! Start your logging!

Create an instance of the logger start logging to your hearts content.

namespace MyNamespace
{
  public class MyClass
  {
    private Logger logger = LogManager.GetCurrentClassLogger();

    public void MyMethod() 
    {
        logger.Trace("Trace Message");
        logger.Debug("{0} Message", "Debug");
        logger.Info("{0} {1}", "Informational", "Message");
        ...

        logger.Log(LogLevel.Trace, "Informational Message");
        logger.Log(LogLevel.Debug, "{0} Message", "Debug");
        ...
    }
  }
}