.NET Corner

.NET, Jeans and ... (From CAS to "Why by default my progressbar in VS.NET generated installation is not being themed?")

<December 2008>
SuMoTuWeThFrSa
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910


Navigation

Blogs I Read

Just .NET

All Posts

Game Programming

Misc.

Currently Reading

Subscriptions

Post Categories



Zero Touch Application Logger

Exception handling is an important art and the truth is that it is tricky to make consistant and full-proof. There are lot of classic articles on exceptional handling of exceptions, cost of stack un-winding, global vs. local handling etc. and the manifestation of the its importance is evident from the inclusion in the Microsoft Enterprise Application Block. It's bizzare and stupid to think hardly any piece of professional quality software comes without robust exception handling policy. But still there will be time when code reviewer mistakenly skips a part which demands a SEH or Structured Exception Handling or something like that. Especially it would be excellent for an ASP.NET web application that already deployed to production server to show the logged dump of those "rare" unhandled exceptions.

This relationship is not entirely correct :

HTTP Module : .NET Fx :: ISAPI Filter : IIS

HTTP modules are more advanced filters in comparison with ISAPI one. Once registered they are dynamically picked up and injected into the ASP.NET runtime pipeline that happens within the context of a HttpApplication. More importantly they can took part in the global events' invocations as someone used to do in Global.aspx file. To handle any unhandled exception you simply have to hook the Error event of the contextual HttpApplication object

public class WebLoggerModule : IHttpModule
{
      
public WebLoggerModule()
     {
     }

     public virtual void Init(HttpApplication WebApplication)
     {
         WebApplication.Error +=
new EventHandler(OnError);
     }

    public virtual void Dispose()
   
{
        
//Clean-up resources
        
return;
   
}

    private void OnError(object sender, EventArgs e)
  
{
        //

   }

It's not recommended to maintain any state in the HTTP module implementation class for obvious reasons(AppDomain recycling...etc). Once you are inside the invocation handler its easy to get contextual application

HttpApplication WebApplication = (HttpApplication) sender;

Also note that any this will fire before any invocation handler registered by the application. Because HTTP modules are processed at much earlier stage in entire HttpRuntime's application call stack(Incoming mode or Reqest mode). The logger simply tries to get the last error and the innermost exception to unlock actual exception source. The actual logging policy could vary widely depending on the companies. In this eaxmple I have used a simple file based logger. Sometimes simple loggers are nicer compared to full-blown logging application block(Be aware of recursive call while getting exception in logging the exception !!!).

try
{
      //Get the web application instance
      
HttpApplication WebApplication = (HttpApplication) sender;

      
//Get the last exception which causes this event to be fired
      
Exception lastException = WebApplication.Server.GetLastError();

      
if (lastException != null)
      {
            
//Try to get the innermost exception from the wrapped-up
            
Exception deepestException = lastException;
            
while(deepestException.InnerException != null)
            {
                  deepestException = deepestException.InnerException;
            }

            if (deepestException != null)
            {
                  
//Get the method's name which has caused this exception
                  
sMethodName = GetMethodWhereExceptionOccurred(deepestException.StackTrace);

                  
//Get the class's name which has caused the exception
                  
sClassName = GetClassWhereExceptionOccurred(deepestException.StackTrace);

                  //Log using common logger
                  
FileLogger oLogger = 
                              Logger.GetLogger(sClassName,sMethodName,LoggerType.File);
                  oLogger.LogError("SYSTEM ERROR : " + deepestException.Message);
            }

      }

}
catch(Exception localException)
{
      Trace.WriteLine(localException.Message);
}

 Only thing left is to register the HTTP module so that ASP.NET runtime can pick it up. It is done through web.config's section.  Detail description of registering a module is available in any ASP.NET book or MSDN Documentation. Just copy the assembly to bin folder of the application you want to monitor. From the next requests and onward the ZTWL(Zero Touch Web Logger...wow) will be right there at HttpApplication's call chain.


posted on Saturday, November 12, 2005 3:29 PM by debasish





Powered by Dot Net Junkies, by Telligent Systems