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.
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.