Profiling ASP.NET MVC using the EQATEC Profiler

I recently have had a need to do some code profiling of an ASP.NET MVC site I have been working on and so, being the cheapskate I am, found the EQATEC .NET Profiler.

Now, there are a couple of caveats to using this profiler for ASP.NET applications.  The first is that the profiler outputs its XML data file to one of the following locations: /Storage Card, /SD Card, /Temp or /.  The best way around this is to create a Temp directory in the root directory of the drive that hosts your ASP.NET application (eg. C:\Temp if your site is located in C:\Inetpub\...).  Make sure the IIS User associated with the relevant App Pool has Write access to this dir, and you’re sweet.

The second caveat is slightly more difficult to get around.  The problem is that the profiler will only output its XML file either when the Main method exits, or when the TakeProfileSnapshot() method is called in the Profiler.Runtime library.  We don’t have a Main method in ASP.NET, so we’ll use the TakeProfileSnapshot() call.

While the following is particularly focussed on ASP.NET MVC, it should be useful for ‘standard’ ASP.NET as well.

First, we need to create a page that will call the TakeProfileSnapshot() method.  In my site, I have a ‘Setup’ Controller for performing tasks that only I know about (such as initially populating databases, etc), so I added a TriggerProfile action to this method and added a simple view to display the output, as follows.

public ActionResult TriggerProfile()
{
    try
    {
        ViewData[“Result”] = “Success”;
    }
    catch (Exception ex)
    {
        ViewData[“Result”] = “Failed: ” + ex.Message + “

” + ex.ToString();
    }
    return View();
}

We’ll flesh it out in a bit.  The  TriggerProfile.aspx page simply has a <%= ViewData["Result"] %> tag to display the result.  Feel free to make this a bit prettier, but let’s face it – nobody but you should ever see this.

I didn’t want to include the EQATEC Profiler DLL in my project, as I don’t really like the idea of modifying a project for testing unless that change is transparent in production.

Reflection to the rescue!

Making sure you add a using System.Reflection; directive, add the following to that try {} block above, before the ViewData["Result"] = "Success"; line:

Assembly eqatec = Assembly.Load(“EQATECProfilerRuntime, Version=1.2.60.0, Culture=neutral, PublicKeyToken=f1beac79aa82eef6”);
Type runtime = eqatec.GetType(“EQATEC.Profiler.Runtime”);

MethodInfo takeSnapshot = runtime.GetMethod(“TakeProfileSnapshot”, new Type[] { });
takeSnapshot.Invoke(null, null);

So what’s happening here?

The EQATECProfilerRuntime.dll assembly is only present in the application once the bin folder has been profiled (the Profiler creates a bin (Profiled) folder – just rename this to bin and remember to restart IIS to activate the changes).  If the /Setup/TriggerProfile page is called in this case, it finds the dll, gets an instance of the TakeProfileSnapshot() method and invokes it, triggering a dump of the profiler output.  In the case that the code has not been profiled, EQATECProfilerRuntime.dll should not be present, and so the Assembly.Load(...) call will fail, and the output of the Exception will be displayed.

To use all of this, simply use the Profiler to profile the bin folder, rename the created folder back to bin, restart IIS and start browsing on those troublesome pages.  When you’re ready, make a call to the /Setup/TriggerProfile page (hopefully you’ll get a “Success” message), and check the C:\Temp folder for the resultant XML.

Happy profiling!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s