CODEDIGEST
Home » Articles
Search
 

Technologies
 

Sponsored links
 

CodeDigest Navigation
 

Technology News
No News Feeds available at this time.
 

Community News
No News Feeds available at this time.
 
Exception/Error Logging in Asp.Net Using log4net – PART 2

By Bala Murugan
Posted On Oct 20, 2012
Article Rating:
Average Rating: 1
No of Ratings: 1
No of Comments: 1
Category: ASP.Net
Print this article.

Exception/Error Logging in Asp.Net Using log4net – PART 2

 

In Part 1 of this article series, we have seen some of the basic configurations of log4net framework to configure error logging in Asp.Net applications. The log4net framework is designed in such a way so that we can customize it to any level to fit in our needs. In this part, we will see more about customizing the log4net framework which will be more useful in real time applications.

Refer Part 1 of this article series to know about initial configurations and settings.

 

Customizing the Loggers

Logging with different Appenders in Same application

We can customize the log4net framework to a granular level where we can log some specific logs to a separate source and rest to the default source. For example, to log all exception from a specific business rules engine(Demo.Math.Utillities namespace below) to SQL server and rest of the logs to a text file we can use the below configuration.

 

namespace Demo.Math.Utillities

{

    public class ArithmeticEngine

    {

        private static readonly ILog log = LogManager.GetLogger(typeof(ArithmeticEngine));

 

        public ArithmeticEngine()

        {

            //

            // TODO: Add constructor logic here

            //

        }

 

        public double Div(int n1, int n2)

        {

            double result = 0;

            try

            {

                result = n1 / n2;

            }

            catch (Exception ex)

            {

                log.Fatal(ex.Message, ex);

            }

 

            return result;

        }

    }

}

Configuration

<log4net>

  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">

      <file value="D:\Technicals\Log4Net\Logs\example.log"/>

      <appendToFile value="true"/>

      <maximumFileSize value="100KB"/>

      <maxSizeRollBackups value="2"/>

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%level %thread %logger - %message%newline"/>

      </layout>

    </appender>

 

<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">

      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <connectionString value="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />

      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />

      <parameter>

        <parameterName value="@log_date" />

        <dbType value="DateTime" />

        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />

      </parameter>

      <parameter>

        <parameterName value="@thread" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%thread" />

      </parameter>

      <parameter>

        <parameterName value="@log_level" />

        <dbType value="String" />

        <size value="50" />

        <layout type="log4net.Layout.PatternLayout" value="%level" />

      </parameter>

      <parameter>

        <parameterName value="@logger" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%logger" />

      </parameter>

      <parameter>

        <parameterName value="@message" />

        <dbType value="String" />

        <size value="4000" />

        <layout type="log4net.Layout.PatternLayout" value="%message" />

      </parameter>

    </appender>

 

    <logger name="Demo.Math.Utillities.ArithmeticEngine">

      <level value="DEBUG" />

      <appender-ref ref="AdoNetAppender_SqlServer"/>

    </logger>

 

 

    <root>

      <level value="ALL"/>           

      <appender-ref ref="RollingFile"/>

    </root>   

</log4net>

 

The settings will log the exception generated from Demo.Math.Utillities namespace to SqlServer table. See below.

Exception logging with Log4Net in Asp.net

 

Apart from the SqlServer table, the exception message will also be logged to text file because of logger’s inheritance. By default, the loggers configured in an application will follow a hierarchy and will inherit the properties from their parent logger. For example, every logger in an application will inherit from root logger. Thus, the logger Demo.Math.Utillities will inherit from root logger and hence the exception will also be logged to both text file and Sql server with the above setting. Similarly, if there is a logger defined in a class under Demo.Math namespace then the loggers defined in Demo.Math.Utillities will inherit them. To prevent the duplicate logging, you can set additivity property of a logger to false if you want to prevent it from inheriting from their parent logger. In our example, to prevent the logging from Demo.Math.Utillities logger to text file you can set additivity=”false”. Something like below,

 

<logger name="Demo.Math.Utillities.ArithmeticEngine" additivity="false">

      <level value="DEBUG" />

      <appender-ref ref="AdoNetAppender_SqlServer"/>

    </logger>

 




 

Adding custom message field

Sometimes, we may require logging some custom information apart from what the log4net framework logs by default. For example, we may need to log the stack trace whenever an exception is thrown for debugging purpose.  To do this, we can add a custom property using ThreadContext class and send our custom information to the appender. Refer the below code,

 

namespace Demo.Math.Utillities

{

    public class ArithmeticEngine

    {

        private static readonly ILog log = LogManager.GetLogger(typeof(ArithmeticEngine));

 

        public ArithmeticEngine()

        {

            //

            // TODO: Add constructor logic here

            //

        }

 

        public double Div(int n1, int n2)

        {

            double result = 0;

            try

            {

                result = n1 / n2;

            }

            catch (Exception ex)

            {

                ThreadContext.Properties["StackTrace"] = ex.StackTrace;

                log.Fatal(ex.Message, ex);

            }

 

            return result;

        }

    }

}

 

Configuration

<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">

      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <connectionString value="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />

      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[StackTrace]) VALUES (@log_date, @thread, @log_level, @logger, @message,@StackTrace)" />

      <parameter>

        <parameterName value="@log_date" />

        <dbType value="DateTime" />

        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />

      </parameter>

      <parameter>

        <parameterName value="@thread" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%thread" />

      </parameter>

      <parameter>

        <parameterName value="@log_level" />

        <dbType value="String" />

        <size value="50" />

        <layout type="log4net.Layout.PatternLayout" value="%level" />

      </parameter>

      <parameter>

        <parameterName value="@logger" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%logger" />

      </parameter>

      <parameter>

        <parameterName value="@message" />

        <dbType value="String" />

        <size value="4000" />

        <layout type="log4net.Layout.PatternLayout" value="%message" />

      </parameter>

      <parameter>

        <parameterName value="@StackTrace" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%property{StackTrace}" />

      </parameter>

    </appender>

 

Conclusion

Thus, with part 1 and part 2 of this article series we have seen how to integrate log4net framework for logging in Asp.Net applications. In the above code samples, I have included the code that logs using log4net directly with the application code just for demonstration. You can define your own logging class with some re-usable logging methods using log4net framework and use these methods instead of calling log4net API methods directly. This helps to make your code clear and even replace the log4net with a different framework with less code change.

Happy coding!!

Similar Articles
You can contribute to CodeDiget.Com:
Donate to CodeDigest.com
Article Feedback
Comments
drop database
test