Configuring Log4Net for use with an Azure Cloud Service

This post is nothing more than just a quick write up of getting Log4Net – your favorite logging framework, otherwise you wouldn’t be reading this – to work in Microsoft’s Azure Cloud. Ah, well … Let me be more precise: Get it to work primarily locally on your development box, where Azure is nicely emulated.

Assuming you’ve just created a new Azure Cloud Service Project with a WebRole (I’ve picked the WCF Service Library from the available Templates) you should:

First add Log4Net to your Web.Config as follows

<configsections  >
        <section name="TraceAppender" type="log4net.Appender.TraceAppender"  >
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
    <immediateflush value="true">
    <layout type="log4net.Layout.PatternLayout">
         <conversionpattern value="%date %level %thread %logger - %message%newline">
  <root value="ALL">
    <level ref="TraceAppender">

Secondly configure the TraceListener in the Web.Config as follows

   <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
    <filter type="" />

Thirdly configure the sources for traces in the WebRole’s OnStart()

public override bool OnStart()
var diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();

var directories = diagConfig.Directories;
var infrastructureDiagnostics = diagConfig.DiagnosticInfrastructureLogs;
var applicationLogs = diagConfig.Logs;
var eventLogs = diagConfig.WindowsEventLog;

applicationLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
infrastructureDiagnostics.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
eventLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);

infrastructureDiagnostics.ScheduledTransferLogLevelFilter = LogLevel.Undefined;
applicationLogs.ScheduledTransferLogLevelFilter = LogLevel.Undefined;
eventLogs.ScheduledTransferLogLevelFilter = LogLevel.Undefined;

DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", diagConfig);

// For information on handling configuration changes
// see the MSDN topic at

return base.OnStart();

Last but not least: Initialize the XmlConfigurator in your AssemblyInfo.cs

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

But why does this work (on a local development box)?

  1. Because the DiagnosticMonitor was started with “Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString” and for the local development box this value is set to “UseDevelopmentStorage=true” (which you can see for yourself in the settings file ServiceConfiguration.local.cscfg)
  2. Because we configured an Application Log and told it to “flush” (=transfer) once every minute its buffers (into an Azure table)
  3. Because in the Web.Config we configured Log4Net to use the log4net.Appender.TraceAppender
  4. Because we have patience and wait a few minutes upon the first time testing (because if the Azure Table does not exist it needs to be created – See for yourself by right-clicking on the emulator icon in your system tray and follow the “console” output of the Compute Emulator UI)
  5. Because we know that we need to click Server Explorer in Visual Studio, followed by Azure > Storage > (Development) > Tables > WADLogsTable to find the Log Entries
Share this Story:
  • facebook
  • twitter
  • gplus

About mavawie