Friday, September 23, 2011

Exception log simplified

One of very common problem is to keep log of exception/error which happens in production environment for debugging and quality improvement purpose.

There are many great logging tools/framework available in the market with many enhanced functionality. In most cases these detailed functionalities are not required.

Few weeks back, when this problem presented itself (to log exception detail to database or file) I thought let’s make things simpler.

Problem Description: Quickly log exception details without any 3rd party framework.

Conditions:

  1. Where to log exceptions details was controlled by system parameter and can be managed from UI.
  2. Exception log method should have ability to log more details if required and supplied.
Solution
  1. Method to get exception details for log
  2. Decide which logging method(s) to call
  3. Implementation of various logging methods


public static void ProcessError(Exception exception, string otherDetails = "")
{
 StackTrace stackTrace = new StackTrace();
 string methodName = stackTrace.GetFrame(1).GetMethod().Name;
 string className = stackTrace.GetFrame(1).GetMethod().DeclaringType.Name;
 string classDetail = string.Format("{0}.{1}", className, methodName);
 string exceptionDetail = string.Format("Error occurred in {0}. {1}Message:{2}", 
  classDetail,
  Environment.NewLine,
  exception.Message
 );

 if (!string.IsNullOrWhiteSpace(otherDetails))
 {
  exceptionDetail = string.Format("{0}{1}Other Details: {2}.",
   exceptionDetail,
   Environment.NewLine,
   otherDetails
  );
 }
 // send this detail for saving
 LogError(exceptionDetail);
}

Here the trick is to get Calling method and class name for logging. We used following lines to do that job

// to get name of calling method
string methodName = stackTrace.GetFrame(1).GetMethod().Name; 

// to get name of calling class
string className = stackTrace.GetFrame(1).GetMethod().DeclaringType.Name; 

Now lets decide where to save this detail



public enum LogMethods
{
 Database,
 File,
 Email
};


...
...


public static void LogError(string exceptionDetail)
{
 switch (errorLogMethod)
 {
  case LogMethods.Database:
   LogErrorInDatabase(exceptionDetail);
   break;
  case LogMethods.File:
   LogErrorInFile(exceptionDetail);
   break;
  case LogMethods.Email:
   SendErrorLog(exceptionDetail);
   break;
  case default:
   SendErrorLog(exceptionDetail);
   break;
 }
}

Now last step, implement save methods


Here is an example of saving detail in database. Similarly other methods can be implemented.


public static void logErrorMessageInDB(string exceptionDetail, string methodName)
{
 try
 {
  MyDataContext myDC = DataContext;

  Log lerror = new Log
  {
   FullDescription = exceptionDetail,
   MethodName = methodName,
   CreateDataTime = DateTime.Now
  };

  iDC.Log.InsertOnSubmit(lerror);
  iDC.SubmitChanges();
 }
 catch (Exception exp)
 {
  /*
   LogErrorInFile(exp);
   // OR
   LogErrorInEventLog(exp);
  */
 }
}

No comments:

Post a Comment