Sunday, February 27, 2011

Tracing Program Execution, My Dream Came True

Tracing, has been an obsession of mine for a long time. Why? Because I want to be ready when a customer calls and says that the application crashed and just before displayed:

"Object reference not set to an instance of an object"

How can you troubleshoot this or any form of unexpected error? If you do not have a backup plan. Installing any debugging tools on a customer production server is generally a no-no.

What I want is to be able to turn a switch and ask the customer to redo the same scenario,
but this time we are going to record in a file
  • All the method calls with all the parameters values 
  • All the exceptions and where they were caught or raised.
  • All information that the developer, saw as important to troubleshoot the application
In 1998, with VB6 I used a custom tool that would insert in the source code
  • Error handlers for each method, and trace the error
  • At the top of each method a call to a specific function passing the class name, the method name and the parameters values.
Around 2005 I wrote the same thing in C#, and thanks to reflection it was easier and the source code needed in each method was smaller. But I still had to insert myself call to trace methods and exceptions.

AOP
I knew about AOP (Aspect Oriented Programming), and I knew it was the solution, but I did not find a framework simple enough that could do what I wanted. I knew about the Spring.net framework and Unity and Castle Windsor dependency injection framework to support some level of AOP. But they require to use interfaces and virtual methods all over the place.

I knew that the company preemptive.com has some kind of solution, I never looked at it.

I think that the library used by Code Contract to inject code in an assembly after compilation is available to anybody, if you look for it.

This week, I listened to DotNetRocks episode 640 Gael Fraiteur is Still PostSharp!.

Well PostSharp is what I was totally looking for.

I installed it and the Trace sample works great, but this information displayed is not that fantastic.

Starting with the sample I wrote my own Aspect, that is the word, to implement tracing to a file the way I want it. Among other thing, when parameters of type Array, List<T> and Dictionary<K,V> are used the content is traced, the return value of each function is also traced. And every thing with the right indentation.

The Trace
Here is a screenshot of fLogViewer.net viewing a trace file. As you can see parameters name and value are part of the trace. Dictionary content are defined with { } and list or array are defined with [ ] (I like Python). Exception caught or un caught will be traced.


The Source code
All you need to do is to applied one attribute to a class, this is the magic of PostSharp and set a logger instance.

using DynamicSugarSharp;

[Tracer]
class TracedClass {

  // code here
}

static void Main(string[] args) {

  Tracer.Logger = new CachedTextFileWriter();
}

The FullTraceAttribute Attribute require an object implementing the ILogger interface,
to start tracing. The class CachedTextFileWriter implement tracing to a file.
A file is created in the %TEMP% folder based on the name of the executing program or you can set the property FileName. Writing to the file is temporarily cached to avoid writing to the disk too often and slow down too much the application. Now be aware that when the trace is on this will slow down the application.

Using Tracing with ASP.NET (MVC or not)

In the past I used my own manual AOP to implement tracing for ASP.NET application. When I was troubleshooting a problem there was most likely one user on the production system. So every thing worked out great. But it is not thread safe. Now creating a thread safe singleton to be used under the ASP.NET framework should be possible.

Dynamic Sugar Sharp Library

I made my FullTrace Attribute part of the Dynamic Sugar Sharp Library as I will release it soon on codeplex.com.

To use the attribute you must
  • Download and install PostSharp. To get a community free license click on 
    • The Start Menu -> PostSharp -> PostSharp User Option
    • Request a free license
    To implement tracing you do not need to buy a license, this is the beauty of open-source, which i am not sure I totally understand. A commercial license is $340, but it is not that obvious what are the features you are paying for.
    • Reference the assembly PostSharp.dll.
    • Reference the assembly DynamicSugarSharp.dll
    • Mark you classes with the attribute[DynamicSugarSharp.FullTrace]

    1 comment:

    1. Nice post. Are you missing the source code? Can't seem to find a link

      ReplyDelete