Zac Gross

Code & More

Azure Log4Net Appender

| Comments

Recently when deploying an existing codebase to Azure I required the ability to configure log4net to write to azure storage services.

After some quick googling I found a NuGet package that seemed to be fairly well maintained and had a modest amount of users according to the NuGet download stats. NuGet Package here: http://www.nuget.org/packages/log4net.Appender.Azure/ or type the following in package manager console:

1
 Install-Package log4net.Appender.Azure

However I immediately ran into a few issues, first problems building it with my project as it was built with dependencies on older frameworks such as log4net. Additionally when running the table appender in a real application with multiple concurrent loggers I began to get errors related to the way it submitted batch inserts to the storage service.

I was able to fork the NuGet project on github, update it’s dependencies, and fix the batch processing issue, you can find my branch here: https://github.com/zacg/log4net.Azure I have submitted a pull request for these changes, hopefully they will appear in the next NuGet package release.

Once referenced just choose your preferred storage method and set your connection string like so:

Azure Appender Config Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<log4net>
    <appender name="TableAppender" type="log4net.Appender.AzureTableAppender, log4net.Appender.Azure">
      <param name="TableName" value="testLoggingTable"/>
      <param name="ConnectionString" value="UseDevelopmentStorage=true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
      </layout>
    </appender>
    <appender name="BlobAppender" type="log4net.Appender.AzureBlobAppender, log4net.Appender.Azure">
      <param name="ContainerName" value="testloggingblob"/>
      <param name="DirectoryName" value="logs"/>
      <param name="ConnectionString" value="UseDevelopmentStorage=true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
      </layout>
    </appender>
    <root>
      <level value="INFO"/>
      <appender-ref ref="TableAppender"/>
      <appender-ref ref="BlobAppender"/>
    </root>
  </log4net>

If you ever have to debug log4net appenders here are a few snippets that may help you. The first is a function to flush the log buffers. The second turns on log4net debug logging, it will log to system.diagnostic.trace, just place the app setting in your config file. And the last snippet is just a setting to write your trace logs to file, again place in your config file.

Flush Buffers
1
2
3
4
5
6
7
8
9
10
11
12
13
//From: Alconja @ http://stackoverflow.com/questions/2045935/is-there-anyway-to-programmably-flush-the-buffer-in-log4net
public void FlushBuffers()
{
    ILoggerRepository rep = LogManager.GetRepository();
    foreach (IAppender appender in rep.GetAppenders())
    {
        var buffered = appender as BufferingAppenderSkeleton;
        if (buffered != null)
        {
            buffered.Flush();
        }
    }
}
Log log4net Debugging Info
1
2
3
  <appSettings>
    <add key="log4net.Internal.Debug" value="true"/>
  </appSettings>
Dump Trace Logs to File
1
2
3
4
5
6
7
8
9
10
 <system.diagnostics>
    <trace>
     <listeners>
  <add
       name="textWriterTraceListener"
       type="System.Diagnostics.TextWriterTraceListener"
       initializeData="C:\dev\log4net.txt" />
       </listeners>
    </trace>
  </system.diagnostics>

And finally a list of the errors encountered and fixed to help out random googlers.

  • Could not load file or assembly ‘log4net, Version=1.2.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a’ or one of its dependencies.
  • WRN: Comparing the assembly name resulted in the mismatch: Build Number
  • All entities in a single batch operation must have the same partition key

I ran into a few roadblocks along the way but ended up with a working log4net appender that can write logs to Azure storage services with a few simple configuration settings. If you have any comments feel free to share below.

Source Code Here: https://github.com/zacg/log4net.Azure

Comments