R&D: Tracer Class for Automatic Logging of Method Entry and Exit

Topics: Logging Application Block, Policy Injection Application Block
Jul 15, 2012 at 11:10 AM

Hi there,

I want tracing in every function Entry and Exit. Say my class contains three methods MethodA MethodB MethodC... Through the Instance someone called MethodA and methodA calls MethodB and MethodB calls methodC

public class test
{
Public void MethodA()
{
MethodB();
}
public void MethodB()
{
MethodC();
}
public void MethodC()
{
}
}

Now when someone calls like test obj = new test(); and obj.MethodA(); I want the tracer to write in database something like "Entered MethodA" in next row "Entered MethodB" next row "Entered MethodC" and then "Exited MethodC" "Exited MethodB" and finally "Exited Method a"

My restriction is: I am not supposed to write this trace code in every method entry and exit. I want this to happen automatically. Just make a Key of App.config file to true and the tracer should start action and false means tracing disable.

 

This we want to debug a Live production application.

 

To do this we got two ways:

Wrap the instance of Test class with a policy using a Policy Injection Applicaiton block: create a policyhandler from ICallHandler then create a MatchingRule, in the MatchingRule read the app.config file and return true if Tracing is enabled else false.

Disadvantage of doing so is: Everytime we create an Instance of any class through the Policy container, the system will read the app.config file and then read the policies present in the configuration file even if the tracing is disabled... This may degrade performance...

 

We found another approach i.e. Tracer class present inside the Logging Application Block. It has something like Method Entry Method Exit functionality. http://www.michaelhamrah.com/blog/2010/02/performance-tracing-for-your-applications-via-enterprise-library/

 

Please provide some more Idea about Tracer class. Can my requirement fit to plug a Tracer class.

 

Many Thanks,

Suraj

Jul 17, 2012 at 11:28 AM

ohh c'mon Exparts why this thread is so silent

Jul 18, 2012 at 5:14 AM

Your requirements sound like it calls for Aspect Oriented Programming.  One way to do that is as you've described using Policy Injection.  If you are concerned about the performance I would suggest to do a quick implementation and test to see the actual impact.

The second approach, using a Tracer (or something similar), doesn't really meet your requirements since it requires instantiating the object and then disposing of the object.  Typically this is done manually along with a using statement.  Depending on your design it may be possible to create an elegant wrapper that takes an Action or Func (or lambda) and internally instantiates a Tracer, invokes the method, and then disposes the Tracer.  It could get messy very quickly, though.

An alternative would be to use an Aspect Oriented framework such as PostSharp.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 18, 2012 at 5:59 AM
Edited Jul 18, 2012 at 6:04 AM

You are one genious guy! Thats correct... Through Action Delegates we can achieve this... But the issue is:

1) If i go for Action Delegate and write the Using(Tracer...) code inside that and call that action delegate, how can I pass extra information i.e. method signatures with start trace logging and return values to end trace logging? There is now way I can push Extended Properties into Tracer class

2) The Tracer class logging the name of the Wrapper class function where the actual USING(Tracer t = new..) is written. Its write like

Entered into DebugWrapper... Exited from DebugWrapper but I want

Entered into BusinessFunction... Exited from BusinessFunction

Here is my codee 

 

 

 

        /// <summary>
        /// Debugs an Code Snippet
        /// </summary>
        /// <typeparam name="T">The Type to Debug</typeparam>
        /// <param name="pAction">The Action to Debug</param>
        /// <param name="pSignature">The Method Signature to write in Trace Database</param>
        public void Debug<T>(Action<T> pAction, String pSignature) where T : new()
        {
            //TODO: R&D to Write Calling Method instead of current Method i.e. Debug
            using (Tracer t = new Tracer("Debug")) 
            {
                T vObject = new T();
                pAction(vObject);
            }
        }

And here is how I call this:

 

 

LogWriter.DebugApplication<ChorusSampleBusinessOperation>((vChorusSampleBusinessOperation) =>

{vChorusSampleEntity = vChorusSampleBusinessOperation.WishCustomer(composite);},"Testing Signature" );

 
3) Is there any code which usages tracer class to achieve this functionalities?
4) Using this code I have to read the app.config file for the IsTraceEnabled key everytime I create any type instance. This may degrade performance. Is there any other way using which I can Enable\Disable tracing on fly for a LIVE application.
Many Thanks,
Suraj

 

 

 

Jul 18, 2012 at 6:38 AM

Oh yeah forgot to mention... Postshap is not in our budget :-)

Jul 18, 2012 at 7:23 AM

There is not that much magic to the Tracer class.  If it doesn't suit your needs 100% then you can easily create your own Tracer implementation based off of the Enterprise Library source code.  Configuration information is loaded into memory so you shouldn't be reading from disk on every check of the property.  If you want to automatically refresh when the configuration changes you can look at using the FileConfigurationSource which automatically refreshes the configuration.

Also note that the preferred approach now is to use the TraceManager class in lieu of direct instantiation of the Tracer class. See Tracing Activities and Propagating Context Information.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 20, 2012 at 5:52 AM

Thanks a lot Randy. Your post helped me.

 

Many Thanks,

Suraj