Saturday, February 13, 2010

SQL Logging with log4net & ASP.NET MVC








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!


Shout it

kick it on DotNetKicks.com

blog comments powered by Disqus
Related Posts Plugin for WordPress, Blogger...