Hello All
Today I will go through logging with Log4net. Log4Net is a logging framework ( a rich library) for .NET. Log4Net is popular for its simplicity and robustness. We can write log in various way though we generally write log only in file we we can also mail log, show in console,save in datatbase as well as write in file in different ways.
First we have to download the Log4Net and add the log4net.dll in our implementation project. In the example I have take 2 projects named LogWriter and LogRunner accordingly, In one project I have implemented the logging and in another I execute that logging method.
My project structure is as image bellow :
In the LogWriter I have take two class as bellow :
LogLevel.cs: In this class I simply define a enum which basically helps to define my log level in my LogUtil class.
namespace LogWriter { public enum LogLevel { DEBUG, ERROR, FATAL, INFO, WARN } }
LogUtil.cs: In this class I have a static method named WriteLog which take 2 parameters one define log level and another take log message as string.
using log4net; using log4net.Config; namespace LogWriter { public static class LogUtil { private static ILog logger = LogManager.GetLogger(typeof(LogUtil)); static LogUtil() { XmlConfigurator.Configure(); } public static void WriteLog(LogLevel logLevel,string log) { if (logLevel.Equals(LogLevel.DEBUG)) { logger.Debug(log); } else if (logLevel.Equals(LogLevel.ERROR)) { logger.Error(log); } else if (logLevel.Equals(LogLevel.FATAL)) { logger.Fatal(log); } else if (logLevel.Equals(LogLevel.INFO)) { logger.Info(log); } else if (logLevel.Equals(LogLevel.WARN)) { logger.Warn(log); } } } }
As I am writing a console application so my mail runner file is Program.cs which is as bellow but you can follow the same procedure in different place as per you requirement.
using System; using LogWriter; namespace LogRunner { class Program { static void Main(string[] args) { try { throw new Exception(); } catch (Exception exc) { LogUtil.WriteLog(LogLevel.DEBUG, "Debug mode logging"); LogUtil.WriteLog(LogLevel.ERROR, "Error mode logging"); LogUtil.WriteLog(LogLevel.FATAL, "Fatal mode logging"); LogUtil.WriteLog(LogLevel.INFO, "Info mode logging"); LogUtil.WriteLog(LogLevel.WARN, "Warn mode logging"); Console.ReadKey(); } } } }
Now one of the most important thing I will focus is log4net configuration. We can configure it from web.config or app.config . In my example I have configured it app.config file in my LogRunner project. In the app.config file follow the commented section.
My configuration file is as bellow , please go through the commented line to get know in detail such as log file rolling, max log file number & size, Log level etc.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender"> <!-- Log file locaation --> <param name="File" value="C:\Users\sanzeeb\Documents\Visual Studio 2008\Projects\Solution1\LogWriter\Log\" /> <param name="AppendToFile" value="true" /> <!-- Maximum size of a log file --> <maximumFileSize value="2KB" /> <!--Maximum number of log file --> <maxSizeRollBackups value="8" /> <!--Set rolling style of log file --> <param name="RollingStyle" value="Composite" /> <param name="StaticLogFileName" value="false" /> <param name="DatePattern" value=".yyyy-MM-dd.lo\g" /> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %-5p %m%n" /> </layout> </appender> <!-- Appender layout fix to view in console--> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" > <layout type="log4net.Layout.PatternLayout"> <param name="Header" value="[Header]\r\n" /> <param name="Footer" value="[Footer]\r\n" /> <param name="ConversionPattern" value="%d [%t] %-5p %m%n" /> </layout> </appender> <!-- Database appender --> <!-- You need to create a table as bellow to insert log in database for MSSQL server. 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 ) --> <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="100" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="Data Source=SANZEEB-PC\SQLEXPRESS;Initial Catalog=AppTesterDB;Integrated Security=True" /> <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <root> <level value="DEBUG" /> <!-- Log level priority in descending order: FATAL = 1 show log -> FATAL ERROR = 2 show log -> FATAL ERROR WARN = 3 show log -> FATAL ERROR WARN INFO = 4 show log -> FATAL ERROR WARN INFO DEBUG = 5 show log -> FATAL ERROR WARN INFO DEBUG --> <!—To write log in file --> <appender-ref ref="LogFileAppender" /> <!--To view log in console --> <appender-ref ref="ConsoleAppender" /> <!--To write log in file batabase --> <appender-ref ref="AdoNetAppender" /> </root> </log4net> </configuration>
Hope this will help to improve your logging in your .NET application.
Thanks
That’s all for today.
BYE




Maik says:
Thx for the tutorial, nice and quick overview to get started quickly!
November 27, 2009, 2:33 pmAnonymous says:
why don't you use "switch case" in your static "WriteLog" methode? just for the look
November 27, 2009, 5:53 pmGW says:
This is my version of your code, I'm not sure if creating the logger for each category has any huge downside or not, please let me know if you know. I was thinking about having a static collection to persist the loggers and be able to call them up from that by name.
These names allowed me to replace the old
using Microsoft.Practices.EnterpriseLibrary.Logging;
that we were using, with:
using Log4netWriter;
Then modify the Logger.Write() calls very slightly, and then was ready to log with log4net
namespace Log4netWriter
{
public static class Logger
{
static Logger()
{
XmlConfigurator.Configure();
}
public static void Write(string message, string category, TraceEventType logLevel)
{
ILog Logger = LogManager.GetLogger(category);
switch (logLevel)
December 15, 2009, 8:39 pm{
case TraceEventType.Verbose:
Logger.Debug(message);
break;
case TraceEventType.Error:
Logger.Error(message);
break;
case TraceEventType.Critical:
Logger.Fatal(message);
break;
case TraceEventType.Information:
Logger.Info(message);
break;
case TraceEventType.Warning:
Logger.Warn(message);
break;
}
}
}
}
Tanvir Anowar says:
Hello GW and others … thanks for you comments. It's definitely a good idea to used switch case and make the log write static,it shouldn't suppose to have drawback.
December 23, 2009, 4:25 pmwindows 7 says:
Absolutely brilliant post guys, been following your blog for 3 days now and i should say i am starting to like your post. and now how do i subscribe to your blog?
November 20, 2010, 5:44 am