I wanted to get some logging action on my latest project and I’ve heard a lot about log4net so I thought I’d give it a whirl. My goal was to have a simple interface that implements log4net and writes to SQL Server. With that said, my interface ended up looking like this:
public interface ILoggingService
{
void Log(string message);
}
I told you it was simple :)
Okay, now let’s go ahead and implement the ILoggingService like this:
public class LoggingService : ILoggingService
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void Log(string message)
{
log.Info(message);
}
}
This particular implementation is only going to log informational type things and not errors or warnings. Basically I want it for auditing purposes. Note: LogManager is part of log4net.
So let’s go on and configure log4net. First we’ll create an IStartUpTask, see this post for more info on the IStartUpTask.
public class log4netConfigurator : IStartUpTask
{
public void Configure()
{
log4net.Config.XmlConfigurator.Configure();
}
}
I’m going to configure log4net in my web.config. I’ve seen a lot of people have a separate log4net.config file, but I want to just put mine in the web.config. So let’s add a log4net section to the <configSections> like this:
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
Now we can add the section to the web.config like this:
<log4net>
<root>
<level value="ALL"/>
<appender-ref ref="ADONetAppender"/>
</root>
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value="1"/>
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<connectionString value="server=serverNAME; uid=userNAME; pwd=passWORD; database=databaseNAME"/>
<commandText value="INSERT INTO ChangePasswordLog ([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>
</log4net>
Okay, so I have an appender setup here to write to my DB.I think it’s pretty self explanatory, if you disagree, post me a comment and I’ll go into more detail. One hiccup I ran into was the bufferSize because I kept trying to test to see if it was writing to my DB and nothing was showing up. The reason being…I didn’t have 100 log entries. I changed the bufferSize to 1 and POOF my record showed up :)
So now in my controller, I accept an ILoggingService in the constructor like this:
private readonly ILoggingService _loggingService;
public HomeController(ILoggingService loggingService)
{
_loggingService = loggingService;
}
So now I can call my Log method from any of my actions like this:
var changePasswordService = DI.ChangePasswordService(username);
changePasswordService.ChangePassword(form.ValidationToken, form.Password);
_loggingService.Log("Password changed for user " + username);
All done! Now I have logging in my app.
Thanks for reading!