views:

142

answers:

5

On every break on the Production/QA/Dev getting to the root of the exception is very crucial and time taking process.

As the web applications are in multi user environment and Stateless \ Asynchronous (HTTP) ,its really a tough job to look at the Eventviewer / log files and root cause an issue reported by the end user; Also it depends on how educated the End-user to explain the issue in detail.

I came up with a creative way to log the Exceptions. Which makes the job easier for the End user and Dev team?

We will follow a signature to log the Exceptions into an XML file, and which can be processed remotely for viewing or reports on Exceptions

The signature of the Static method in the Error logging class is as follows

WriteLog (Unique Number , Module Name, Priority, Layer ,String Custom Message,Exception with Stack Trace);

I know there are many reusable Exception handling libraries, but what I was looking at is a unique number to track the issue that should get displayed to the end user

Response back to the User :

If the Exception is expected to handled and consumed then it’s up the developer to show the valid user-friendly message to the end user. Incase of any unexpected or exception is thrown to the Application layer ( Global .asax ) the Response would be cleared and Custom Message in HTML will be written back to the user with the Unique ID like the below one

“ An Unexpected Error has occurred , the Exception has be recorded for further action; Please use the # Unique number generated to communicate the Support team “

Parameter Details :

Unique Number : This is the unique number generated for every Exception, a read only (get) property in the ErrorLogging Class which would be unique per exception , this would be concatenation of the Hour+Minutes+Seconds+Milliseconds; initially I thought to use GUID but then it would be tough for the end user to remember the GUID to report the issue.

Public string strExceptionID {

      Get { 

      return  DateTime.Now.ToString(“HHmmssfff”);

          }    

     }

Module Name : This would be a Static Enum variable with Module Name Ex : enum ModuleName {

    Module1, 

    Module2, 

    Module3  };

Priority: This would be a Static Enum variable with Priority , developer has to decide the priority like if it’s a validation fail of Date or integer format use “Low” or if its unexpected in a Business layer call then use “2” .

I think Priority High should be used in only in DAL or in Business Logic Layer or like if the interface to SAP or Ariba fails. Ex : enum Priority {

        High =1, 
      Medium =2, 
      Low =3, };

Layer :

This would be a Static Enum variable with Layer Ex : enum Layer {

      Presentation, 
      Business, 
      DataAccess 
            };

String Custom Message :

This is optional parameter, and its upto the developer to supply an information to help explain the Reason or Empty string can be passed.

Exception with Stack Trace : This would the Exception object which would be further processed inside the method.

The processing done inside the error log method :

The method will additionally get the logged-in Userid and timestamp and write it to the XML File.

Pros :

-> XML Logging will enable us to process an use it in any manner -> The exceptions can be viewed remotely in a browser. -> Easy to trace and find any exception. -> We can search , sort exception based on Module, Priority , Time Stamp , UserID…etc -> We can generate reports @ Module level , Layer wise , Priority , Time…

Cons : Dependency on the XML file, if its lost all the exceptions would go for a toss, we can overcome this in two ways; writing the xml to DB on timely basis OR write this on top of Event viewer logging as we'll always have the backup.

Based on the review comments I'll post the XML Schema and the ASPX page to view and search the errors.

Please take time to review and give ur feedback.

A: 

I have two remarks:

  1. I don't like relying on timestamps as unique identifiers. If you know for sure your site is not going to be loaded it's ok, but under heavy stress the milliseconds resolution may not be enough. The reason being the milliseconds counter might have a granularity larger than one. This means two very close calls might get the same timestamp. Not very likely, but why limit yourself?

  2. Presenting a code to the user along with a human readable message is nice, but you should never expect the user to contact you and point you to the error. If you're looking for feedback on errors, just have the logger send you an email whenever the error occurs (which means you will be able to use a real unique identifier, like a GUID, rather than a timestamp).

eran
A: 

For the ExceptionID, you might actually be best-off with a GUID. The date format will not be unique, because it rolls over every day, and also, you may get multiple errors in the same millisecond.

Andy White
A: 

Emphasizing the point made by previous reviewers: You're likely to get multiple exceptions in the same millisecond, if and when there are failures caused by race conditions.

Dan Breslau
+3  A: 

Hi there,

I have a bit of a bug bear with people rewriting tracing APIs without really understanding what the platform will give them out of the box. So lets look at you API call:

WriteLog (Unique Number , Module Name, Priority, Layer ,String Custom Message,Exception with Stack Trace);

Unique Number: Implement a TraceListener (check out System.Diagnostics) which adds this unique number, don't make the calling code generate it.

Module Name: The stack trace will provide this kind of detail - assuming you know what code is in what module. In fact it probably doesn't matter from a fault finding perspective.

Priority: The System.Diagnostics API provides the following level of severity. Information, Warning and Error (as well as Debug). Now priority is in the eye of the beholder, from a development point of view - it is either "hey this happened, you might like to know (information)", he "this looks a bit suss be we can continue anyway (warning)" and "oh heck, I'm broken (error)".

Layer: What is the real difference between module and error here? Once again, if you use System.Diagnostics correctly environmental information such as what computer this happened on can be added dynamically. You wouldn't want to rely on developers to do this consistently.

Custom Message: Yep - this is reasonable. For bonus points make it take a format string (actually - Trace.TraceError/TraceWarning/TraceInformation already do this. So just use that.

Exception: If you use Trace.TraceError (et.al) then you can use the format string. Not every error has an exception so you don't necessarily need to produce an API that accepts them, as long as they take a format string - you can do this:

Trace.TraceError( "The user provided the following input '{0}'. The follow exception was:\r\n{1}", userInput, ex );

Anyway - I guess what I am saying is that if you are writing this in .NET like it looks like you are - spend half a day surfing the System.Diagnostics documentation. You might negate the need to write your API.

Mitch Denny
A: 

If this is an ASP.NET application, then you should look into ASP.NET Health Monitoring. Even by default, it will emit detailed traces into the event log. You can configure it to produce the same output in XML files, and add your own tracing as well.

John Saunders