Log4Net custom LayoutPattern


A few days ago I had a nice little task at my workplace: To add a custom “key” to the log4net pattern layout.

I like log4net and was quite happy to be given time to dive into the belly of the beast. But I quickly noticed that most of the information on the web is outdated and simply wrong with the current version.

The most useful information I got was from a blog post from Scot Hanselman http://www.hanselman.com/blog/CreatingYourOwnCustomPatternLayoutPatternParserAndPatternConvertorWithLog4net.aspx. Sadly log4net has moved along since that blog was written.

Where I failed in the current version was the fact that the PatternParser class is sealed thus making any inheritance attempts void.

After some Googleing and reading the log4net SDK I found the solution to be simple and elegant at the same time. All you have to do is to create two classes:

  • PatternConverter
  • PatternLayout

And you are done.

The first class you have to implement is a PatternConverter which will actually handle the new key you want to add. The implementation is straight forward and easy to do. An example would look like this:

using System.IO;
using log4net.Util;
namespace MyCustomLog4NetPattern
{
  public class CustomPatternConverter : PatternConverter
  {
    protected override void Convert(TextWriter writer, object state)
    {
      writer.Write("Message to add");
    }
  }
}

The object that gets passed in is actually the LoggingEvent that has triggered the log operation. Sou if you need additional resources from there they are available. Additionally to this you can access all the environment variables that you thing should be placed in the log.

A little word of advice: Do not apply any formatting to the string you write. So no newlines or any other fancy formating.

After that is implemented we can move on to the PatternLayout. This is again an almost empty inheritance story. Which will look like this:

using log4net.Layout;
namespace MyCustomLog4NetPattern
{
  public class CustomPatternLayout : PatternLayout
  {
    public CustomPatternLayout()
    {
      AddConverter(new ConverterInfo{Name = "your_key", Type = typeof(CustomPatternConverter )});
    }
  }
}

And that is it! You are done. Every time that the string %your_key appears in the appender layout your little converter will be called and the placeholder replaced.

If now you want to use your custom “key” on a rolling file appender the configuration would look like this:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="Log/log.txt" />
  <appendToFile value="true" />
  <rollingStyle value="Composite" />
  <datePattern value="yyyyMMdd" />
  <maxSizeRollBackups value="10" />
  <maximumFileSize value="1MB" />
  <layout type="MyCustomLog4NetPattern.CustomPatternLayout, MyCustomLog4NetPattern">
    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline - My stuff: %your_key%newline" />
  </layout>
</appender>

Ant that is all that there is to this. easy and simple solution.

Hope that this will save somebody some time in the future 🙂

Advertisements

2 thoughts on “Log4Net custom LayoutPattern

  1. Great simple solution.
    Ques: Is it possible to get different value for key – your_key instead of “Message to add” in the example. I am trying to pass value from the application and would like to add more than one custom key to the log/DB, more specific to the application. How can I do that?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s