Dionoid

ALL WEB MUST SCALE!
4 Tips for using Log4NET's ADONetAppender in ASP.NET

I'm using Log4NET for almost a year now, and I must say I'm very pleased with it. This logging framework is very easy to learn and extend; same goes for installation and configuration.

The most commonly used log4net appender is probably the ADONetAppender (look at Ryan's post for an easy walkthrough to set this up). However, I spent a couple of hours getting the ADONetAppender working the way I want. If you're also using the ADONetAppender, these tips can be helpful.

Tip 1: Configure log4net on Application_Start
After adding the log4net configSection and appenders in your web.config, you need to run this line of code in the Application_Start of your Global.asax:

log4net.Config.DOMConfigurator.Configure();
I've no clue why log4net needs this extra kickstart here, because I think the Log4NetConfigurationSectionHandler should be able do this configuration itself.

Tip 2: In the ADONetAppender settings (inside web.config), set the bufferSize to 1.
A lot of examples show a bufferSize of 100, which means nothing is written to the Log table until 100 messages are logged. This is probably the reason why most developers think ADONetAppender doesn't work properly.

Tip 3: Change the settings of an appender at runtime.
The ADONetAppender has a connectionString setting, which contains the connectionstring to the database where the Log table is located. However, most WebApplications already have a connectionstring defined somewhere in the web.config (for instance in the appSettings), and you don't want the connectionstring defined twice or more. Assume my logger is called 'MyProject', and contains a reference to the ADONetAppender:

<logger name="MyProject">
  <appender-ref ref="ADONetAppender" />
</logger>

Now you can add this piece of code in the Application_Start (inside global.asax) to change the connectionString setting of the ADONetAppender at runtime to the value of the "MyConnectionString" appSetting in the web.config:

// Get the Hierarchy object that organizes the loggers
log4net.Repository.Hierarchy.Hierarchy hier =
  log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy;

if (hier != null)
{
  //get ADONetAppender
  log4net.Appender.ADONetAppender adoAppender =
    (log4net.Appender.ADONetAppender)hier.GetLogger("MyProject",
      hier.LoggerFactory).GetAppender("ADONetAppender");
  if (adoAppender != null)
  {
    adoAppender.ConnectionString =
      System.Configuration.ConfigurationSettings.AppSettings["MyConnectionString"];
    adoAppender.ActivateOptions(); //refresh settings of appender
  }
}

Tip 4: Use log4net's MDC (Mapped Diagnostic Context) to add extra information to your Log table.
The ADONetAppender is very easy to extend. If want to add the name of the current user to the Log table, you can do this in three steps:
  1. Add a new column 'User' to the Log table
  2. When logging a message, use MDC.Set("user", ...) to add the user name to the log4net context
  3. Change the commandText of the ADONetAppender in the web.config and add a parameter to 
      hold the user name (using the %X{user} conversion pattern)
 
The log4net MDC.Set() code:

public void LogError (string message, Exception e)
{
  //get logger
  ILog logger = LogManager.GetLogger("MyProject");

  //set user to log4net context, so we can use %X{user} in the appenders
  if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
    MDC.Set("user", HttpContext.Current.User.Identity.Name);

  if (logger.IsErrorEnabled)
    logger.Error(message, e); //now log error
}

The appender in web.config:

<!--
CREATE TABLE [dbo].[Log] (
 [Id] [int] IDENTITY (1, 1) NOT NULL,
 [Date] [datetime] NOT NULL,
 [Thread] [varchar] (255) NOT NULL,
 [Level] [varchar] (50) NOT NULL,
 [Logger] [varchar] (255) NOT NULL,
 [User] [varchar] (50) NULL,
 [Message] [varchar] (4000) NOT NULL,
 [Exception] [varchar] (2000) NULL
)
-->
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
 <bufferSize value="1" />
 <connectionType value="System.Data.SqlClient.SqlConnection, System.Data,
 Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
 <connectionString value="[we will set this automatically at runtime]" />
 <commandText value="INSERT INTO Log ([Date],[Level],[Logger],[User],[Message],[Exception])
 VALUES (@log_date, @log_level, @logger, @user, @message, @exception)" />
 <parameter>
  <parameterName value="@log_date" />
  <dbType value="DateTime" />
  <layout type="log4net.Layout.RawTimeStampLayout" />
 </parameter>
 <parameter>
  <parameterName value="@log_level" />
  <dbType value="String" />
  <size value="50" />
  <layout type="log4net.Layout.PatternLayout">
   <conversionPattern value="%p" />
  </layout>
 </parameter>
 <parameter>
  <parameterName value="@logger" />
  <dbType value="String" />
  <size value="255" />
  <layout type="log4net.Layout.PatternLayout">
   <conversionPattern value="%c" />
  </layout>
 </parameter>
 <parameterName value="@user" />
  <dbType value="String" />
  <size value="50" />
  <layout type="log4net.Layout.PatternLayout">
   <conversionPattern value="%X{user}" />
  </layout>
 </parameter>
 
 <parameter>
  <parameterName value="@message" />
  <dbType value="String" />
  <size value="4000" />
  <layout type="log4net.Layout.PatternLayout">
   <conversionPattern value="%m" />
  </layout>
 </parameter>
 <parameter>
  <parameterName value="@exception" />
  <dbType value="String" />
  <size value="2000" />
  <layout type="log4net.Layout.ExceptionLayout" />
 </parameter>
</appender>

Published Wednesday, February 16, 2005 11:13 PM by Dr.NETjes

Filed under: ,

Comments

# re: Log4Net is Crap4Crap@ Saturday, February 19, 2005 9:42 PM

TrackBack

# Log4Net@ Tuesday, May 17, 2005 3:34 PM

TrackBack

# re: 4 Tips for using Log4NET's ADONetAppender in ASP.NET@ Thursday, May 07, 2009 8:53 PM

In log4net 1.2.10 the MDC (Mapped Diagnostic Context) has been replaced with thread context properties.

See logging.apache.org/.../contexts.html

Daniel Ballinger

# Links@ Friday, July 31, 2009 11:24 AM

Hi, Welcome to my my links page. Here I am keeping web links which i find useful for me and interesting

Syed Akbar Ali

# Changing log4net connection string at runtime@ Thursday, December 03, 2009 2:49 PM

On my current project, we log with log4net.&#160; This project is still kicking, and I still love using it.&#160; It is a bit dated though, and there are things that probably should work out of the box, but just don’t. One of those things is the AdoNetAppender

b#

# [Ejemplo] Usando la API Apache Log4Net@ Thursday, September 16, 2010 5:09 PM

Estaba dando mantenimiento a un proyecto que fue desarrollado con Java (Struts), y en el&#160; código

SergioTarrillo - RichWeblog

# log4net Connection String Blues &laquo; A Day In The Lyf@ Friday, December 31, 2010 12:42 PM

Pingback from  log4net Connection String Blues &laquo; A Day In The Lyf

log4net Connection String Blues « A Day In The Lyf

# Development Fun by dtomalino - Pearltrees@ Wednesday, January 11, 2012 3:11 AM

Pingback from  Development Fun by dtomalino - Pearltrees

Development Fun by dtomalino - Pearltrees

Leave a Comment

(required) 
(required) 
(optional)
(required)