C#

Creating Log4Net appenders programatically in c#

In most cases using log4net’s xml configuration is best to set up how your application will log. However I found it more practical to create the configuration programatically in a shared c# file, to easily add common options between my applications.

First create a static class to hold the following methods and add using:

using log4net;
using log4net.Core;
using log4net.Repository.Hierarchy;
using log4net.Appender;
using log4net.Layout;
using log4net.Filter;
 

a file appender

public static IAppender CreateFileAppender(string appCode)
{
RollingFileAppender appender = new RollingFileAppender();
appender.Name = “RollingFileAppender”;
appender.File = String.Format(@”c:\logs\{0}\{0}.log”, appCode);
appender.AppendToFile = false;
appender.RollingStyle = RollingFileAppender.RollingMode.Size;
appender.MaxSizeRollBackups = 10;
appender.MaximumFileSize = “1000MB”;

PatternLayout layout = new PatternLayout();
layout.ConversionPattern = “
%newline%date %-5level %logger – %message – %property%newline”;
layout.ActivateOptions();

appender.Layout = layout;
appender.ActivateOptions();

return appender;
}

A console appender

public static IAppender CreateConsoleAppender()
{
ConsoleAppender appender = new ConsoleAppender();
appender.Name = “ConsoleAppender”;
PatternLayout layout = new PatternLayout();
layout.ConversionPattern =
“%newline%date %-5level %logger – %message – %property%newline”;
layout.ActivateOptions();

appender.Layout = layout;
appender.ActivateOptions();

return appender;
}

An ADO.NET appender

public static IAppender CreateAdoNetAppender(string cs)
{
AdoNetAppender appender = new AdoNetAppender();
appender.Name = “AdoNetAppender”;
appender.BufferSize = 1;
appender.ConnectionType = “System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”;
appender.ConnectionString = cs;
appender.CommandText = @”INSERT INTO LogNet
([DateUtc],[Thread],[Level],[Logger],[User],[Message],[Exception]) VALUES
(@date,@appcode,@thread,@level,@logger,@user,@message,@exception)”;

AddDateTimeParameterToAppender(appender, “date”);
AddStringParameterToAppender(appender, “thread”, 20, “%thread”);
AddStringParameterToAppender(appender, “level”, 10, “%level”);
AddStringParameterToAppender(appender, “logger”, 200, “%logger”);
AddStringParameterToAppender(appender, “user”, 20, “%property{user}”);
AddStringParameterToAppender(appender, “message”, 1000,
“%message%newline%property”);
AddErrorParameterToAppender(appender, “exception”, 4000);
appender.ActivateOptions();
return appender;
}

The above requires 3 helper functions:

public static void AddStringParameterToAppender(this log4net.Appender.AdoNetAppender appender, string paramName,
int size, string conversionPattern)
{
AdoNetAppenderParameter param = new AdoNetAppenderParameter();
param.ParameterName = paramName;
param.DbType = System.Data.DbType.String;
param.Size = size;
param.Layout = new Layout2RawLayoutAdapter(new PatternLayout(conversionPattern));
appender.AddParameter(param);
}

public static void AddDateTimeParameterToAppender(this log4net.Appender.AdoNetAppender appender, string paramName)
{
AdoNetAppenderParameter param = new AdoNetAppenderParameter();
param.ParameterName = paramName;
param.DbType = System.Data.DbType.DateTime;
param.Layout = new RawUtcTimeStampLayout();
appender.AddParameter(param);
}

public static void AddErrorParameterToAppender(this log4net.Appender.AdoNetAppender appender, string paramName, int size)
{
AdoNetAppenderParameter param = new AdoNetAppenderParameter();
param.ParameterName = paramName;
param.DbType = System.Data.DbType.String;
param.Size = size;
param.Layout = new Layout2RawLayoutAdapter(new ExceptionLayout());
appender.AddParameter(param);
}

Initializing log4net

Now you can easily initialize log4not in the startup of your application. Here are some extra helper functions:

public static void ConfigureWithFile(string appCode)
{
Hierarchy h = (Hierarchy)LogManager.GetRepository();
h.Root.Level = Level.All;
h.Root.AddAppender(CreateFileAppender(appCode));
h.Configured = true;
}

public static void ConfigureWithDb(string cs, bool onlyErrors)
{
Hierarchy h = (Hierarchy)LogManager.GetRepository();
h.Root.Level = Level.All;

IAppender ado = CreateAdoNetAppender(appCode, cs);
h.Root.AddAppender(ado);
if (onlyErrors)
{
var filter = new LevelRangeFilter();
filter.LevelMin = Level.Error;
((AppenderSkeleton)ado).AddFilter(filter);
}

h.Configured = true;
}

So now, if example you have a web application:

protected void Application_Start(object sender, EventArgs e)
{
LogHelpers.ConfigureWithDb(
@”Data Source=.\SQL2008;Initial Catalog=Today;Integrated Security=True”,false);
LogHelpers.ConfigureWithFile(“MyWebApp”);
}

The above would log to the database (only the errors) plus a file (all log levels). The rest is all the same, e.g. to get the logger instance:

public static readonly ILog Log =
LogManager.GetLogger(typeof(MyClass));

Advertisements

One thought on “Creating Log4Net appenders programatically in c#

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