I'm toying with the idea of extending the AdoNetAppender to add the
ability to run additional queries after a defined time period. The
syntax would look something like this:

<appender name="TableMaintenceAdoNetAppender"
type="log4net.Appender.AdoNetAppender">
 <connectionType value="..." />
 <connectionString value="..." />
 <commandText value="..." />
 <tableMaintence>
  <interval value="3600" />
  <commandType="StoredProcedure" />
  <commandText value="FLUSH_DEBUG_LOGS" />
 </tableMaintence>
 <tableMaintence>
  <interval value="43200" />
  <commandText value="DELETE FROM Logs WHERE Level = 'INFO'" />
 </tableMaintence>
 <tableMaintence>
  <interval value="86400" />
  <commandText value="DELETE FROM Logs WHERE Level = 'WARN'" />
 </tableMaintence>
</appender>

The implementation is pretty straight forward:

// untested
protected override void SendBuffer(log4net.Core.LoggingEvent[] events)
{
 base.SendBuffer(events);
 if (Connection != null && 
     Connection.State == ConnectionState.Open)
 {
  foreach (TableMaintence tableMaintence in tableMaintenceList)
  {
   if (tableMaintence.NeedsFlushing() == true)
   {
    try
    {
     using(IDbCommand cmd = Connection.CreateCommand())
     {
      cmd.CommandType = tableMaintence.CommandType;
      cmd.CommandText = tableMaintence.CommandText;
      cmd.ExecuteNonQuery();
     }
     tableMaintence.UpdateNextFlush();
    }
    catch(Exception ex)
    {
     ErrorHandler.Error("Exception while writing to database.", ex);
    }
   }
  }
 }
}

The down side is that NeedsFlush() will be called for each
<tableMaintence> node after every log message if the buffer size of the
base appender is set to 1. I'd like to add some sort of Timer so that
the statements are called ever <interval> seconds and not just when log
statements are written. I understand the code in this article:

 http://www.eggheadcafe.com/articles/20040916.asp

but I'd rather not add a HttpModule to the web.config for my appender
to work. Is it possible to create a static array of Timers; one timer
for each interval? My gut tells me this is a BadIdea. 

I want to allow a list of <tableMaintence> nodes to be executed, not
just one.

I know I've asked this question before but I'm not sure how it applies
to custom properties on appenders such as the <commandText> node inside
of a <tableMaintence> node. Does the value attribute of my
<commandText. mode accept PatternStrings?

<!-- is this syntax valid ??? -->
<commandText type="log4net.Layout.PatternLayout,log4net">
 <conversionPattern value="%m" />
</commandText>

I know that %m will most likely not contain anything meaningful in this
context.

Thanks,
Ron

Reply via email to