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:
[sourcecode language=”csharp”]
using log4net;
using log4net.Core;
using log4net.Repository.Hierarchy;
using log4net.Appender;
using log4net.Layout;
using log4net.Filter;
[/sourcecode]
A file appender
[sourcecode language=”csharp”]
public static IAppender CreateFileAppender(string appCode)
{
var appender = new RollingFileAppender
{
Name = "RollingFileAppender",
File = String.Format(@"C:\logs\{0}.log", appCode),
AppendToFile = false,
RollingStyle = RollingFileAppender.RollingMode.Size,
MaxSizeRollBackups = 10,
MaximumFileSize = "100MB"
};
var layout = new PatternLayout
{
ConversionPattern = "%newline%date %-5level %logger – %message – %property%newline"
};
layout.ActivateOptions();
appender.Layout = layout;
appender.ActivateOptions();
return appender;
}
[/sourcecode]
A console appender
[sourcecode language=”csharp”]
public static IAppender CreateConsoleAppender()
{
var appender = new ConsoleAppender {Name = "ConsoleAppender"};
var layout = new PatternLayout
{
ConversionPattern = "%newline%date %-5level %logger – %message – %property%newline"
};
layout.ActivateOptions();
appender.Layout = layout;
appender.ActivateOptions();
return appender;
}
[/sourcecode]
An ADO.NET appender
[sourcecode language=”csharp”]
public static IAppender CreateAdoNetAppender(string cs)
{
var appender = new AdoNetAppender
{
Name = "AdoNetAppender",
BufferSize = 1,
ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
ConnectionString = cs,
CommandText = @"INSERT INTO Log ([Date], [Thread], [Level], [Logger], [Message], [Exception], [User], [Ip]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @user, @ip)"
};
AddDateTimeParameterToAppender(appender, "log_date");
AddStringParameterToAppender(appender, "thread", 255, "%thread");
AddStringParameterToAppender(appender, "log_level", 50, "%level");
AddStringParameterToAppender(appender, "logger", 255, "%logger");
AddStringParameterToAppender(appender, "message", 4000, "%message");
AddStringParameterToAppender(appender, "user", 50, "%aspnet-request{AUTH_USER}");
AddStringParameterToAppender(appender, "ip", 15, "%aspnet-request{REMOTE_ADDR}");
AddErrorParameterToAppender(appender, "exception", 2000);
appender.ActivateOptions();
return appender;
}
[/sourcecode]
The above requires 3 helper functions:
[sourcecode language=”csharp”]
public static void AddStringParameterToAppender(this AdoNetAppender appender, string paramName, int size, string conversionPattern)
{
var param = new AdoNetAppenderParameter
{
ParameterName = paramName,
DbType = System.Data.DbType.String,
Size = size,
Layout = new Layout2RawLayoutAdapter(new PatternLayout(conversionPattern))
};
appender.AddParameter(param);
}
[/sourcecode]
[sourcecode language=”csharp”]
public static void AddDateTimeParameterToAppender(this AdoNetAppender appender, string paramName)
{
var param = new AdoNetAppenderParameter
{
ParameterName = paramName,
DbType = System.Data.DbType.DateTime,
Layout = new RawUtcTimeStampLayout()
};
appender.AddParameter(param);
}
[/sourcecode]
[sourcecode language=”csharp”]
public static void AddErrorParameterToAppender(this AdoNetAppender appender, string paramName, int size)
{
var param = new AdoNetAppenderParameter
{
ParameterName = paramName,
DbType = System.Data.DbType.String,
Size = size,
Layout = new Layout2RawLayoutAdapter(new ExceptionLayout())
};
appender.AddParameter(param);
}
[/sourcecode]
Initializing log4net
Now you can easily initialize log4not in the startup of your application. Here are some extra helper functions:
[sourcecode language=”csharp”]
public static void ConfigureWithFile(string appCode)
{
var h = (Hierarchy)LogManager.GetRepository();
h.Root.Level = Level.All;
h.Root.AddAppender(CreateFileAppender(appCode));
h.Configured = true;
}
[/sourcecode]
[sourcecode language=”csharp”]
public static void ConfigureWithDb(string cs, bool onlyErrors)
{
var h = (Hierarchy)LogManager.GetRepository();
h.Root.Level = Level.All;
var ado = CreateAdoNetAppender(cs);
h.Root.AddAppender(ado);
if (onlyErrors)
{
var filter = new LevelRangeFilter {LevelMin = Level.Error};
((AppenderSkeleton)ado).AddFilter(filter);
}
h.Configured = true;
}
[/sourcecode]
So now, if example you have a web application:
[sourcecode language=”csharp”]
protected void Application_Start(object sender, EventArgs e)
{
LogHelpers.ConfigureWithDb(@"Data Source=.\SQL2008;Initial Catalog=Today;Integrated Security=True",false);
LogHelpers.ConfigureWithFile("MyWebApp");
}
[/sourcecode]
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:
[sourcecode language=”csharp”]
public static readonly ILog Log = LogManager.GetLogger(typeof(MyClass));
[/sourcecode]
via: http://codesofair.wordpress.com/2012/02/01/creating-log4net-appenders-programatically-in-c/