Using NLog with Windows Azure Cloud Services

NLog is an easy to use logging package that can be plugged into virtually any .net application. In my recent experimentation with the Azure platform, I ran into a few hurdles with NLog integration. Azure is intended to allow for horizontal scaling, so you can’t design for a single ‘box’ running your application. While the benefits are many, the drawback to the architecture is that you can just write a file out to a logs directory on your server. But fear not, friends; there is a fairly easy way to get NLog working with Azure using a few simple config settings.

Before going into details, this post assumes you have the NLog nuget package installed and referenced in your project. It also assumes you know how to add or have already added NLog functionality in your web application.

azure-diagnostics.wadcfg

Find your diagnostics.wadcfg.png file

Azure has a set of diagnostic configurations that can be reviewed in depth in the Azure diagnostic documentation. For our purposes, we want to enable trace logging.  We will then have NLog use the tracing functionality to route the logging data to Azure table storage. Find the ‘diagnostics.wadcfg’ file and open it up. An example file below shows the settings you’ll need; your default file should look similar.  You will likely need to add the line starting with ‘DiagnosticInfrastructureLogs’ and the following line starting with ‘Logs’. PT1M means Poll Time One Minute; this keeps your logging from spamming to the storage table and wasting CPU cycles. The downside is that if you’re doing real-time debugging on a deployed application, you’ll only see your logs update every minute.



<?xml version="1.0" encoding="utf-8"?>
<DiagnosticMonitorConfiguration configurationChangePollInterval="PT1M" overallQuotaInMB="4096" xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
  
  <DiagnosticInfrastructureLogs bufferQuotaInMB="1024" scheduledTransferLogLevelFilter="Verbose" scheduledTransferPeriod="PT1M" />
  <Logs bufferQuotaInMB="1024" scheduledTransferPeriod="PT1M" />  
  <Directories>
    <IISLogs container="wad-iis-logfiles" />
    <CrashDumps container="wad-crash-dumps" />
  </Directories>

  <WindowsEventLog bufferQuotaInMB="1024" scheduledTransferPeriod="PT1M" scheduledTransferLogLevelFilter="Error">
    <DataSource name="Application!*" />
  </WindowsEventLog>
  <PerformanceCounters bufferQuotaInMB="512" scheduledTransferPeriod="PT0M">
    <PerformanceCounterConfiguration counterSpecifier="\Memory\Available MBytes" sampleRate="PT3M" />
    <PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\ISAPI Extension Requests/sec" sampleRate="PT3M"/>
    <PerformanceCounterConfiguration counterSpecifier="\Web Service(_Total)\Bytes Total/Sec" sampleRate="PT3M"/>
    <PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Requests/Sec" sampleRate="PT3M"/>
    <PerformanceCounterConfiguration counterSpecifier="\ASP.NET Applications(__Total__)\Errors Total/Sec" sampleRate="PT3M"/>
    <PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Queued" sampleRate="PT3M"/>
    <PerformanceCounterConfiguration counterSpecifier="\ASP.NET\Requests Rejected" sampleRate="PT3M"/>
  </PerformanceCounters>
  
</DiagnosticMonitorConfiguration>

The next step is to enable NLog to log to the windows diagnostics tracing. Logging to trace simply relays nlog to use the Diagnostic.Trace() methods which Azure will, in turn, send to your logging table. That being said, any code in your solution that uses Diagnostics.Trace() will also end up in your log without the pretty nlog formatting.


<?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">

  <!-- make sure to set 'Copy To Output Directory' option for this file -->
  <!-- go to http://nlog-project.org/wiki/Configuration_file for more information -->

  <targets>
        <target xsi:type="Trace" name="trace" />
  </targets>

    <rules>
        <logger name="*" minlevel="Debug" writeTo="trace" />
    </rules>
</nlog>
Azure-Diagnostic-Data

Viewing data from server explorer

After all is said and done, your NLog entries will end up in your Azure table storage. You can right click on your deployed system and click ‘View Diagnostics Data’ and you’ll get a summary from the last 15 minutes. Alternatively, you can view your data table directly and see all logging.

azure-logs

Azure Log file from table storage

Getting NLog working took a bit of research but after you figure out the processes, it can be used quickly in any new Azure projects. You can also switch your configuration to a local text file when not running from the cloud for quick tracing.

5 thoughts on “Using NLog with Windows Azure Cloud Services

  1. Shawn says:

    Do you have any insight into using nLog with an Azure website? I saw a reference in your post entitled “Windows Azure Cost for the Casual Dev”, to your having moved to Cloud Services only to have then figured out what you did wrong, but there was no additional information 🙁
    Thanks in advance.
    S

    • Shawn says:

      Actually just figured it out… Simply change the filename attribute of the target node for the file to point to the app’s App_Data directory (eg. “${basedir}/App_Data/${shortdate}.log”). Azure will let you write to that location without any hassle.

      • Patrick says:

        I believe your approach will work on Cloud services, with the caveat of it not being shared between multiple web roles. From what I’ve read, with Cloud Services, it is best to write to blob storage since that will allow multiple instances of your web/worker role to all log to the same location. Technically, you can write to app data on a cloud service, but each instance will have it’s own instance of your data.

        Here is some more info:
        Stack Exchange

  2. Pingback: Integrating NLog with Azure Cloud Service Diagnostics | A Technical Perspective

  3. Pingback: Software development bookmarks | Ordo Rerum

Leave a Reply

Your email address will not be published. Required fields are marked *