Add log4net in .Net Application
log4net library
If you are planning to use the log4net library for error/info/warning
logging in your .net project then this post will help you in that. This post
will give you the step by step process to setup and use the log4net library. I have
used a slightly different approach to consume the basic methods of log4net.
Instead of creating a static variable of log4net interface, I created a sealed class and inside that created different methods to log the information. I have used the .net framework 4.5 to take the advantages of CompilerServices. If you don’t know about the CompilerServices refer this link.
Instead of creating a static variable of log4net interface, I created a sealed class and inside that created different methods to log the information. I have used the .net framework 4.5 to take the advantages of CompilerServices. If you don’t know about the CompilerServices refer this link.
Furthermore, this article is going to explain you how to log
the messages in flat file, database logging and sending the log information via
email.
Lets get started
Step 1 – Prerequisite
Download
the latest version of log4net. Or use the neget manager to add the reference.
Step 2 – Add a new class and name it Logger.cs and add the
reference of “System.Runtime.CompilerServices”. I will explain about the
ThreadContext in later steps.
using System.Runtime.CompilerServices;
using log4net;
using System.Diagnostics;
public sealed class Logger
{
public static
log4net.ILog Log {
get; set; }
static Logger()
{
Log = log4net.LogManager.GetLogger(typeof(Logger));
//SetLoggerConnectionString();
ThreadContext.Properties["Priority"] = "0";
ThreadContext.Properties["Severity"] = "Error";
ThreadContext.Properties["Title"] = "FileExchange";
ThreadContext.Properties["MachineName"] = Environment.MachineName;
ThreadContext.Properties["AppDomainName"] = AppDomain.CurrentDomain.ToString();
ThreadContext.Properties["ProcessID"] = Process.GetCurrentProcess().Id;
ThreadContext.Properties["ProcessName"] = Process.GetCurrentProcess().ProcessName;
}
public static void Debug(object meg,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Debug(memberName + System.Environment.NewLine +
sourceFilePath
+ System.Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + System.Environment.NewLine +
meg);
}
public static void Warning(object msg,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Warn(memberName + Environment.NewLine +
sourceFilePath + Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + Environment.NewLine +
msg);
}
public static void Error(Exception ex,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Error(memberName + Environment.NewLine +
sourceFilePath + Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + Environment.NewLine +
ex.Message, ex);
}
public static void Info(object msg,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Info(memberName + Environment.NewLine +
sourceFilePath + Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + Environment.NewLine +
msg);
}
public static void Error(object msg,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Info(memberName + Environment.NewLine +
sourceFilePath + Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + Environment.NewLine +
msg);
}
public static void Fatal(object msg,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
Log.Fatal(memberName + Environment.NewLine +
sourceFilePath + Environment.NewLine +
"Line Number
" +
sourceLineNumber.ToString() + Environment.NewLine +
msg);
}
}
Step 3 – Configuration setting for log4net
Common
Settings
If
you are adding the config changes in your app.config or web.config then you
need to add the below setting
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,
log4net" />
</configSections>
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="ADONetAppender" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="SmtpAppender" />
</root>
</log4net>
Step 4 – Add below configuration under the root element
LogFileAppender Configuration
<appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net">
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<file value="./Log/TestConsole.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout,
log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
ADONetAppender Configuration
You need to specify the connection
string under connectionStrings section
<appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionStringName value="DBConnection" />
<connectionType value="System.Data.SqlClient.SqlConnection,
System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="INSERT INTO LogTable
([Priority],[Severity],[Title],[Timestamp],[MachineName],[AppDomainName],[ProcessID],[ProcessName],[Message])
VALUES (@Priority, @Severity, @Title, @Timestamp,
@MachineName,@AppDomainName,@ProcessID,@ProcessName, @Message)" />
<parameter>
<parameterName value="@Priority" />
<dbType value="String" />
<size value="32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Priority}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Severity" />
<dbType value="String" />
<size value="32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Severity}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Title" />
<dbType value="String" />
<size value="156" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Title}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Timestamp" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@MachineName" />
<dbType value="String" />
<size value="32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{MachineName}" />
</layout>
</parameter>
<parameter>
<parameterName value="@AppDomainName" />
<dbType value="String" />
<size value="512" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{AppDomainName}" />
</layout>
</parameter>
<parameter>
<parameterName value="@ProcessID" />
<dbType value="String" />
<size value="256" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{ProcessID}" />
</layout>
</parameter>
<parameter>
<parameterName value="@ProcessName" />
<dbType value="String" />
<size value="512" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{ProcessName}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Message" />
<dbType value="String" />
<size value="1500" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="ERROR" />
</filter>
</appender>
RollingFileAppender Configuration
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="./Log/TestConsole.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="15" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level
%logger - %message%newline" />
</layout>
</appender>
SmtpAppender Configuration
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
<to value="xyz@xyz.com" />
<from value=" xyz@xyz.com" />
<subject value="test logging message" />
<smtpHost value="SMTP host name" />
<bufferSize value="512" />
<lossy value="false" />
<evaluator type="log4net.Core.LevelEvaluator,log4net">
<threshold value="WARN" />
</evaluator>
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%property{log4net:HostName}
:: %level :: %message %newlineLogger: %logger%newlineThread:
%thread%newlineDate: %date%newlineNDC: %property{NDC}%newline%newline" />
</layout>
Step 5 – for database logging, if your table structure is
different than the default log4net table structure then you need to do extra
coding.
Default
log4net table structure
[Date], [Thread], [Level], [Logger], [Message], [Exception]
In this example, I have used the custom
table and it might be different in your case. The point that I am trying to
make here is that you need to add the other column value ThreadContext (YOU CAN FIND THE CODE IN THE CONSTRUCTOR
(Step 1))
[Priority], [Severity], [Title], [Timestamp], [MachineName], [AppDomainName],
[ProcessID], [ProcessName], [Message]
Step 6 - AssemblyInfo.cs file changes
You need
to add below link of code in AssemblyInfo.cs file to tell the log4net where to
find the configuration.
[assembly: log4net.Config.XmlConfigurator(Watch
= true)]
Step 7 – If you are on this step then you have completed the
99% of work and now you need to use the logger class in your code to log the
messages. Simple example would be
try
{
//Do
something
}
catch (Exception ex)
{
Logger.Debug(ex);
}
Comments