CodeCop Interceptors Profiling

How to profile your .NET application without modifying its code

You wouldn’t believe how many developers exist out there who profile a .NET application by writing instrumentation logic directly and repeatedly onto its code. From tiny to big corporations, on small or large-scale projects you still see people doing this:

  public class SomeAuthenticationService : ISomeAuthenticationService, IApplicationService
    {
        public void Authenticate(User user)
        {
          var stopWatch = new Stopwatch();
          stopWatch.Start();
            
          try
          {  
            DoMethodLogic();
          }
          catch (Exception ex)
          {
            SomeStaticTracingService.IncrementExceptionCounter("AuthenticationService", "Authenticate", ex);
          }
          
          stopWatch.Stop();
          
          SomeStaticTracingService.Write('Authenticate took {0}ms to execute", stopwatch.Elapsed.Milliseconds);
        }
  }

There’s nothing wrong with this sort of approach if you’re doing it for a couple of methods, but imagine you had to instrument more than one application and in total you had 100 services with 10 methods each. Should we still think this is viable?

10 Methods x 100 Services = 1000 Methods

Simple math can show us that is not. If in average you took 3 minutes to instrument a method (and this is already assuming robotic speed) it would take you up to 50 hours to do such a work. You would literally “burn” more than a work week doing this repetitive task when you could be creating awesome stuff that brought real value for your enterprise.

Putting this 50 hours of work in terms of the cost/hour of the developer to the enterprise, if the developer was paid at a rate of $55 USD an hour (assuming this is correct) it would have costed (roughly) $2750 USD to the company for such work. Ouch!

So where does that leave us? What can be done to avoid this? How can we instrument an app with little or no impact on the original source code so that it takes less time to accomplish?

The Answer Is…

Simple. Use a library that enables you to automatically intercept methods and inject this sort of profiling code at runtime. A library that enables you to write the profiling code once and apply it for many. A library that enables you to add or remove profiling code without having to constantly redeploy the profiled app, and such a library is CodeCop.

CodeCop specializes in method interception and it’s not the only player in the market for that matter. The thing is that this library is different from everything that exists out there. It works under a JSON API (although a fluent one also exists) thus making it the very first totally unobtrusive method interception library for the .NET space.

Intrumentation Logic Goes Into Interceptors

CodeCop has this notion of interceptors. These objects act as code “containers” for profiling logic or other. Code inside interceptors can be automatically executed before, after or instead the target method and also when exceptions occur.

This is how we would write a single interceptor with equivalent logic to the above example. The big difference is that we are writing it on a separate assembly, absolutely decoupled from our intercepted application’s code.


 public class ProfilingInterceptor : ICopIntercept, ICopErrorHandle
 {  
    // Code in here will run before the method executes
    public void OnBeforeExecute(InterceptionContext context)
    {
      var stopWatch = new Stopwatch();
      stopWatch.Start();
      
      context.TransferBag.Add("stopwatch", stopwatch);
    }

    // Code in here will run after the method executes
    public void OnAfterExecute(InterceptionContext context)
    {
     var stopwatch = context.TransferBag["stopwatch"] as Stopwatch;
     stopwatch.Stop();

     SomeStaticTracingService.Write('{0} took {1}ms to execute", context.InterceptedMethod.Name, stopwatch.Elapsed.Milliseconds);
    }

     // Code in here will run whenever the execution of the intercepted method fails.
     public void OnError(InterceptionContext context)
     {
        SomeStaticTracingService.IncrementExceptionCounter(context.Sender.GetType().Name, context.InterceptedMethod.Name, context.Exception);
     }


 }

No Touching The Code

Now, how can we make our target methods execute the interceptor code without touching their source?

As I said CodeCop works under a JSON API. Is through this API that we target our interceptors against types and their methods. By not tying the interceptor code directly within our application and using a JSON configuration file we can say that we are working unobtrusively.

But how is this done? Well CodeCop has an online tool that automatically generates this JSON file for you. Just upload your assemblies, the tool will reverse-engineer them and afterwards you can comfortably select the types you want to intercept. All this in a super intuitive, easy to use UI. I’ve written a post that talks about this tool here.

This is a sample of how the JSON file looks like for our example. In a single swoop we applied the ProfilingInterceptor to all the methods of types that implement the IApplicationService interface and that could have taken us probably no more than 5 minutes to accomplish.

{
    "Types": [
        {
            "TypeName": "MyWebApp.IApplicationService , MyWebApp",
            "Methods": [
                {
                    "MethodSignature": "*",
                    "Interceptors": [ "ProfilingInterceptor"]
                }
            ],
          "GenericArgumentTypes": [ ]
        }

    ],
    "GlobalInterceptors": [ ],
    "Key":"Your product key or leave empty for free product mode, limited to 25 methods"

}

By enabling you to apply interceptors in a “bulk” fashion to the IApplicationService interface, all services that implement it will automatically have this profiling code on them.

As you see, no touching the code.

Fitting It All Together

To make the magic happen inside the profiled app all we need is 3 simple steps:

1 – Add the CodeCop assembly as a dependency onto the profiled app.

2- Add the JSON file to the project with the copy local option set to copy if newer.

3- For security reasons (an app must show a clear intent that it wants to be intercepted), issue a single call to Cop.Intercept() method from within your initialization logic (global.asax, owin pipeline or other).

Now sit back and enjoy the show as you got plenty of free time to do it. 🙂

CodeCop Serves More Than Just Profiling

If you liked CodeCop and want to know other use cases for interceptors don’t forget to subscribe to the 5-Day Free Crash Course To Method Interception that is available on the homepage. All subscribers will be getting a 10% discount on all product licenses, so don’t miss this time-bounded opportunity.

Free Email Updates
Get the latest content first.
100% Privacy. No spam.

Liked it? Please Share.

Leave a Reply

Your email address will not be published. Required fields are marked *