Writing An Appender For log4net

2008, Jan 10    

In log4net speak, an appender is an output destination for a log such as a file, the console, a database or even email.  log4net ships with so many appenders that most of us will never need to write our own.  There are cases where you may find a need for your own appender, for example, you may want to log errors to your company's bug tracking software. 

In our case, we simply wanted error logs to pop up a message box with the error and location.  We run this internally so that developers run into errors immediately during development and can break into the debugger to fix them.  We found that logging to a file was too easy to ignore.

MessageBoxAppender

I was pleasantly surprised how easy it is to write a new appender, but there is very little information on the web, so I thought it would be best to give an example.

  1. Create a new Class Library project in Visual Studio.
  2. Add a reference to log4net. My appender also uses MessageBox, so I also added references to System.Drawing and System.Windows.Forms.
  3. Remove the default Class1.cs added to the project.
  4. Add your appender class. In my case, MessageBoxAppender.cs.
  5. You could implement the log4net.Appender.IAppender interface, but it is easiest to derive from log4net.Appender.AppenderSkeleton, then most of the work is done for you.
  6. At a minimum, override the Append method. This is where you do your work.
  7. If you are going to use the RenderLoggingEvent method to create your logging message based on the configured layout (such as PatternLayout), override the RequiresLayout property and return true.
  8. When you configure your appender, you must give the assembly qualified name for your appender.  For example,
  9. </ol>

    </p>

    Here is the simplified code for the MessageBoxAppender that I wrote.

    using System;
    using System.Windows.Forms;
    using System.Diagnostics;
    
    using log4net.Core;
    using log4net.Appender;
    
    namespace Alteridem.log4net
    {
        /// 
        /// Displays a MessageBox for all log messages.
        /// 
        public class MessageBoxAppender : AppenderSkeleton
        {
            /// 
            /// Writes the logging event to a MessageBox
            /// 
            override protected void Append( LoggingEvent loggingEvent )
            {
                string title = string.Format( "{0} {1}",
                    loggingEvent.Level.DisplayName,
                    loggingEvent.LoggerName );
    
                string message = string.Format(
                    "{0}{1}{1}{2}{1}{1}(Yes to continue, No to debug)",
                    RenderLoggingEvent( loggingEvent ),
                    Environment.NewLine,
                    loggingEvent.LocationInformation.FullInfo );
    
                DialogResult result = MessageBox.Show( message, title, MessageBoxButtons.YesNo );
    
                if ( result == DialogResult.No )
                {
                    Debugger.Break();
                }
            }
    
            /// 
            /// This appender requires a  to be set.
            /// 
            override protected bool RequiresLayout
            {
                get { return true; }
            }
        }
    }

    There isn't much to see here. I use the log level and the log name in the titlebar. I display the rendered message string and the calling location in the MessageBox and I break into the debugger if you press No.

    Now, to configure this for your developers to see ERROR messages, the following configuration would work.

    
    
        
            

    The only thing to not here is that the log4netExtensions in the appender line is the assembly.

    This should be enough to give you a basic framework to build whatever type of appender you want.  Every time I delve into a new area of log4net, I am once again surprised how easy it is to work with and how well designed it is.  If you aren't using it, I would highly recommend it.