#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
using System.Data;
using System.Data.SqlClient;
using log4net.Appender;
using log4net.Core;
namespace SampleAppendersApp.Appender
{
///
/// Simple database appender
///
///
///
/// This database appender is very simple and does not support a configurable
/// data schema. The schema supported is hardcoded into the appender.
/// Also by not extending the AppenderSkeleton base class this appender
/// avoids the serializable locking that it enforces.
///
///
/// This appender can be subclassed to change the database connection
/// type, or the database schema supported.
///
///
/// To change the database connection type the
/// method must be overridden.
///
///
/// To change the database schema supported by the appender the
/// and methods must be overridden.
///
///
public class FastDbAppender : IAppender, IBulkAppender, IOptionHandler
{
private string m_name;
private string m_connectionString;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public string ConnectionString
{
get { return m_connectionString; }
set { m_connectionString = value; }
}
public virtual void ActivateOptions()
{
}
public virtual void Close()
{
}
public virtual void DoAppend(LoggingEvent loggingEvent)
{
using(IDbConnection connection = GetConnection())
{
if (connection.State == ConnectionState.Closed)
{
// Open the connection for each event, this takes advantage
// of the builtin connection pooling
connection.Open();
}
using(IDbCommand command = connection.CreateCommand())
{
InitializeCommand(command);
SetCommandValues(command, loggingEvent);
command.ExecuteNonQuery();
}
}
}
public virtual void DoAppend(LoggingEvent[] loggingEvents)
{
using(IDbConnection connection = GetConnection())
{
// Open the connection for each event, this takes advantage
// of the builtin connection pooling
connection.Open();
using(IDbCommand command = connection.CreateCommand())
{
InitializeCommand(command);
foreach(LoggingEvent loggingEvent in loggingEvents)
{
SetCommandValues(command, loggingEvent);
command.ExecuteNonQuery();
}
}
}
}
///
/// Create the connection object
///
/// the connection
///
///
/// This implementation returns a .
/// To change the connection subclass this appender and
/// return a different connection type.
///
///
virtual protected IDbConnection GetConnection()
{
return new SqlConnection(m_connectionString);
}
///
/// Initialize the command object supplied
///
/// the command to initialize
///
///
/// This method must setup the database command and the
/// parameters.
///
///
virtual protected void InitializeCommand(IDbCommand command)
{
command.CommandType = CommandType.Text;
command.CommandText = "INSERT INTO [LogTable] ([Time],[Logger],[Level],[Thread],[Message]) VALUES (@Time,@Logger,@Level,@Thread,@Message)";
IDbDataParameter param;
// @Time
param = command.CreateParameter();
param.ParameterName = "@Time";
param.DbType = DbType.DateTime;
command.Parameters.Add(param);
// @Logger
param = command.CreateParameter();
param.ParameterName = "@Logger";
param.DbType = DbType.String;
command.Parameters.Add(param);
// @Level
param = command.CreateParameter();
param.ParameterName = "@Level";
param.DbType = DbType.String;
command.Parameters.Add(param);
// @Thread
param = command.CreateParameter();
param.ParameterName = "@Thread";
param.DbType = DbType.String;
command.Parameters.Add(param);
// @Message
param = command.CreateParameter();
param.ParameterName = "@Message";
param.DbType = DbType.String;
command.Parameters.Add(param);
}
///
/// Set the values for the command parameters
///
/// the command to update
/// the current logging event to retrieve the values from
///
///
/// Set the values of the parameters created by the
/// method.
///
///
virtual protected void SetCommandValues(IDbCommand command, LoggingEvent loggingEvent)
{
((IDbDataParameter)command.Parameters["@Time"]).Value = loggingEvent.TimeStamp;
((IDbDataParameter)command.Parameters["@Logger"]).Value = loggingEvent.LoggerName;
((IDbDataParameter)command.Parameters["@Level"]).Value = loggingEvent.Level.Name;
((IDbDataParameter)command.Parameters["@Thread"]).Value = loggingEvent.ThreadName;
((IDbDataParameter)command.Parameters["@Message"]).Value = loggingEvent.RenderedMessage;
}
}
}