I have used log4net in numerous projects over the years.
Recently I have been working in MOSS 2007, creating timer jobs, and I certainly saw the value in having a great logging tool like log4net at my disposal.
The timer job will be executed by Windows SharePoint Services Timer service. The service by default runs under the Network Service account.
You will need to put log4net into the GAC. The default log4net distribution comes with a signed assembly for this purpose.
Given that your assembly of the Timer job will live inside the GAC as well, I found that the easiest route was to configure log4net in code. That way we don't have to worry about an extra configuration file.
My preferred logging target in log4net is a database, so the example will log to a dedicated database.
The following function can be used to programmatically configure log4net with one database appender, and selective filtering
public void ConfigureLog4Net(string _LOGGING_CONNECTIONSTRING,bool DEBUGINFO)
{
AdoNetAppender sqlAppender = new AdoNetAppender();
sqlAppender.CommandType = CommandType.Text;
sqlAppender.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
sqlAppender.ConnectionString = _LOGGING_CONNECTIONSTRING;
sqlAppender.CommandText = "INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message,@exception)";
AdoNetAppenderParameter param1 = new AdoNetAppenderParameter();
param1.ParameterName = "@log_date";
param1.Layout = new log4net.Layout.RawTimeStampLayout();
param1.DbType = DbType.DateTime;
sqlAppender.AddParameter(param1);AdoNetAppenderParameter param2 = new AdoNetAppenderParameter();
param2.ParameterName = "@log_level";
param2.Layout = new Layout2RawLayoutAdapter(new log4net.Layout.PatternLayout("%level"));
param2.DbType = DbType.String;
param2.Size = 50;
sqlAppender.AddParameter(param2);
AdoNetAppenderParameter param3 = new AdoNetAppenderParameter();
param3.ParameterName = "@thread";
param3.Layout = new Layout2RawLayoutAdapter(new log4net.Layout.PatternLayout("%thread"));
param3.DbType = DbType.String;
param3.Size = 255;
sqlAppender.AddParameter(param3);
AdoNetAppenderParameter param4 = new AdoNetAppenderParameter();
param4.ParameterName = "@logger";
param4.Layout = new Layout2RawLayoutAdapter(new log4net.Layout.PatternLayout("%logger"));
param4.DbType = DbType.String;
param4.Size = 255;
sqlAppender.AddParameter(param4);AdoNetAppenderParameter param5 = new AdoNetAppenderParameter();
param5.ParameterName = "@message";
param5.DbType = DbType.String;
param5.Layout = new Layout2RawLayoutAdapter(new log4net.Layout.PatternLayout("%message"));
param5.Size = 4000;
sqlAppender.AddParameter(param5);AdoNetAppenderParameter param6 = new AdoNetAppenderParameter();
param6.ParameterName = "@exception";
param6.DbType = DbType.String;
param6.Layout = new Layout2RawLayoutAdapter(new log4net.Layout.ExceptionLayout());
param6.Size = 4000;
sqlAppender.AddParameter(param6);log4net.Filter.LevelRangeFilter filter = new log4net.Filter.LevelRangeFilter();
if (!DEBUGINFO)
{
filter.LevelMin = log4net.Core.Level.Warn;
filter.LevelMax = log4net.Core.Level.Critical;
sqlAppender.AddFilter(filter);
}sqlAppender.BufferSize = 1;
sqlAppender.ActivateOptions();BasicConfigurator.Configure(sqlAppender);
}
The schema for the database the code uses is:
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,
[Message] [varchar](4000) NOT NULL,
[Exception] [varchar](2000) NULL
) ON [PRIMARY]