Back to Blog - lightweight ASP.NET profiler

29 Jun 2016

Over the last year on my spare time, I’ve been working on profiler for ASP.NET apps - This small tool instruments methods from chosen assemblies and visualizes statistics of their execution times.

It has got lower priority for me for a long time because of “Daj Się poznać” and other things but I think this project is worth to finally shed some light on it.

Right now, the tool does just one thing: for every HTTP request, it generates methods time visualization like this (click to enlarge):


Before I go into more details, let me quickly introduce it with some short sample usage.

Profiling eCommerce application

Let’s say we have a site deployed on IIS, called NOP:

IIS configuration

I’m using nopCommerce here (open source e-commerce platform written in .NET stack) as an example of an e-commerce store. I have an instance with sample database, so we will have some real work to do here when the landing page is requested:

nopCommerce sample

Let’s try to profile it via netric. The application itself you can get from here. Download and unpack from the latest release. Once the package is downloaded, we need to install netric_x64.msi (it just registers profiler COM component and adds a bunch of entries in the registry) and then configure it by apm.exe, which can be found in downloaded zip. Two things are to be done:

  • Hook up profiling to NOP site by running following command:
$ apman -i NOP
  • Choose assemblies to be instrumented. There is no need to instrument all loaded assemblies at first, only those from our application, in this case, nopCommerce assemblies. All of them begin with “Nop.” prefix:

NOP assemblies

So we select them like this:

$ apman -asm Nop.*

That’s it. The last step is to reset IIS to apply changes above.

Now we can run netric.exe and then hit the landing page again. After a while, new “Flames” subfolder will be created under the path where netric.exe has been extracted. It is the place where all visualizations are saved. Once the request is completed, netric will add new SVG file with the interactive graph I showed you at the beginning.

How to read a flamegraph

Flamegraph will contain all methods (from Nop.* assemblies) called in a given request, which is marked here simply by URL in the chart title. In our case ,it is “/” which tells us it’s just a request for the home page or root. The easiest way to read the chart is from the bottom to the top: every level indicates (relative) stack depth which starts from the lowest part. So for example, during request execution when something called our custom attribute method, CustomerLastActivityAttribute.OnActionExecuting(), this method called CustomerService.UpdateCustomer() which called EfRepository'1.Update(). At the same time, we can quickly see that this is actually the slowest part because these 3 bars are the widest among all instrumented methods. This is the greatest benefit of visualizing execution time in this way - we can easily compare proportions of bars width in various places in the stack and assess which parts are time-consuming.

Flamegraph is interactive. Some methods will be quite fast, so they will be rendered as very small bars. If you want to examine some, just click on it and the graph will be zoomed to the selected part:

Zooming sample

Different colors don’t mean anything, they are just for readability. They could be leveraged of course in some way, for example for grouping similar methods, but it is not the case in the current version. Flamegraph charts have been invented by Brendan Greg and they are not limited to methods instrumentation. You can find more information on his site.

Why netric?

Basically, today we have several options when it comes to deal with measuring methods time:

  1. Standard profilers - dotTrace, ANTS profiler, Visual Studio. They are mature and developer friendly tools but they are not free and add overhead.
  2. Manual instrumentation with tools like Miniprofiler or some other DIY solution. This is a cheap way to log method execution but still you need to instrument them manually.
  3. Full featured APMs like AppDynamic or New Relic. They are great but costly and of course not comparable with such a simple tool like mine, however, instrumentation solution is pretty similar.

So netric is a kind of merge of those worlds: you can instrument methods of your choice with minimal overhead without the need of introducing changes in the code, for free. Like this, despite typical developer ad-hoc profiling it can be a part of automated performance tests on separate servers (which is the case in the place I work right now).

How it works

All the magic is done thanks to native ICorProfiler API. Netric contains COM component written in C++ that injects special IL code on the runtime which emits metrics through ETW to the agent, netric.exe. This is quite fast solution: the cost of sending metric of one method call was about 400 nanoseconds (yes), on average, on my desktop. Single agent can profile many sites on the same IIS, and of course, multiple requests can be run in parallel.

What’s next?

Ok, this is just the beginning. This is still a prototype and there is a lot of work with this tool. It needs a decent storage and web interface instead of simple SVG files. It would be nice to have better and more flexible configuration. I also have plans to add SQL execution times to flamegraph. But you can say it is already MVP, sort of:)

Source code is on github.