Logging And Tracing With Post Sharp

Introduction

In every project, we use the logging concept to handle the exceptions and trace the applications and their flow. This is why logging and tracing play a very crucial role in application development.

Basically, Logging and Tracing can be implemented in the following ways.

  • We can store it in the Database
  • We can store it in the file system
  • We can store it in the Event viewer
  • We can store it in other ways also

Problem

Let's suppose, we have a web application that contains n number of pages, and on each page, we have so many methods. Now, we have a requirement to implement logging and we started implementing logging class to store all the exceptions in the database. In order to log the exceptions in our application, we have to call those implemented logging class methods on all methods of our application.

Old Solution

To log the exceptions in our application, we need to do the following things in every class of our web application.

  • Create an instance for logging class.
  • Call logging method to store the exception.
  • Pass exception instance to log the exact exception details like Message, Stack Trace, etc.
  • Wrap a try/catch around each method that requires logging and then add the logging code to the catch block.

So, this is a time-consuming process and also, we need to test all those methods.

New Solution

To overcome all the above problems, we have to apply the Sharp concept to logging.

  • Add comprehensive logging to your app without impacting on source code.
  • It’s very easy. You'll be done in minutes and Remove as quickly.
  • Multi-Framework Support. Continue to use your favorite frameworks,log4net, NLog, Enterprise Library, and Diagnostics. Trace, Console
  • High Performance

Benefits of logging with Post Sharp

  • Reduce development cost and time.
  • Build more scalable software.
  • Add functionality more easily after the first release.
  • Help new members contribute quickly.
  • It works on the Aspect Oriented Programming(AOP) concept. So it’s simple to implement and remove.

Installation

Step 1. Install Post Sharp (Post Sharp Express is free for logging) Tool for Visual Studio. (https://www.postsharp.net/download)

Step 2. Add Post Sharp to your project from the NuGet package. Here, we can select which framework to use log4net, NLog, Enterprise Library, Diagnostics. Trace, Console.

Here, I am installing Post Sharp with Nlog.

 NuGet package

Till now, it’s good; right? We have installed the Post Sharp tool for Visual Studio and added NuGet packages to our project. Let’s go for implementation now.

Implementation

Here, we add a new class (TraceAttribute.cs) to the below web application.

using Newtonsoft.Json;
using NLog;
using NLog.Targets;
using PostSharp.Aspects;

namespace Shopping.WebApp
{
    [Serializable]
    public class NlogTraceAttribute : OnMethodBoundaryAspect
    {
        public static Logger Logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// On Method Entry
        /// </summary>
        /// <param name="args"></param>
        public override void OnEntry(MethodExecutionArgs args)
        {
            Logger.Info($"OnEntry : {(args.Method != null ? args.Method.Name : "")}");

            string className, methodName, arguments;
            if (args.Method != null)
                if (args.Method.DeclaringType != null)
                    className = $"{args.Method.DeclaringType.Namespace}.{args.Method.DeclaringType.Name}";
            if (args.Method != null) methodName = args.Method.Name;
            arguments = args.Arguments;

            Logger.Info($"className: {className}; methodName:{methodName};arguments:{arguments}");
        }

        /// <summary>
        /// On Method success
        /// </summary>
        /// <param name="args"></param>
        public override void OnSuccess(MethodExecutionArgs args)
        {
            Logger.Info($"OnSuccess : {(args.Method != null ? args.Method.Name : "")}");
            var returnValue = args.ReturnValue;
            Logger.Info($"ReturnValue : {returnValue}");
        }

        /// <summary>
        /// On Method Exception
        /// </summary>
        /// <param name="args"></param>
        public override void OnException(MethodExecutionArgs args)
        {
            if (args.Exception != null)
                Logger.Info($"OnException : {(!string.IsNullOrEmpty(args.Exception.Message) ? args.Exception.Message : "")}");

            var Message = args.Exception.Message;
            var StackTrace = args.Exception.StackTrace;

            Logger.Info($"Application has got exception in method-{args.Method.Name} and message is {Message}");

            // or you can send email notification
        }

        /// <summary>
        /// On Method Exit
        /// </summary>
        /// <param name="args"></param>
        public override void OnExit(MethodExecutionArgs args)
        {
        }
    }
}

The OnMethodBoundaryAspect aspect results in the target method being wrapped into a try catch finally, block.

You can implement four pieces of advice,

  • OnEntry(MethodExecutionArgs): executed at the beginning of the block;
  • OnSuccess(MethodExecutionArgs): executed only when the method is successful (i.e. does not result in an exception);
  • OnException(MethodExecutionArgs): invoked when the method results in an exception;
  • OnExit(MethodExecutionArgs): always executed after method execution (whether the method resulted in an exception or not).

Parameters
 

args

Type: PostSharp.Aspects.MethodExecutionArgs.

Event arguments specify which method is being executed and what are its arguments.

That’s it. Here we use, Nlog to capture all logging and Tracing into the file system. You can customize in trace class to do logging and tracing based on our requirements.

How to use

It’s very simple to use/integrate the “NlogTraceAttribute” class into the methods of the project.

Now, I have to log in and trace "my Registration" class which has two methods.

public class Registration
{
    public bool RegisterCustomer(string email, string password, string gender, string dateofbirth)
    {

    }

    public void IsExistingCustomer(string email)
    {

    }
}

Yes, it’s a one-minute job. I just need to add the NlogTrace attribute to all the methods. Please look at the class given below.

public class Registration
{
    [NlogTrace]
    public bool RegisterCustomer(string email, string password, string gender, string dateofbirth)
    {

    }

    [NlogTrace]
    public void IsExistingCustomer(string email)
    {

    }
}

It’s simple and takes only a little bit of time and effort to add and remove traces with source code changes. Even new developers also find it easy to implement for their code.

If we want to enable the NlogTrace attribute for all methods on the solution in a single shot, we can use it as below.

[assembly: NlogTraceAttribute]


Similar Articles