Skip to main content

Performance counters in C# made easier


If you ever got to tango with performance counters in C# (+1, they can be very useful) you might have noticed that the current API leaves much to be desired. Things can get even more cluttered when you have a bunch of them. You have to store the name, help string, and type for each one so you can feed it to the API later on. You'll also need to store an instance for each counter so you can have its value updated. The other day a colleague of mine mentioned that the task of adding a new counter becomes a chore.

The good news is, you can make your life easier.
The mechanism that will assist you in doing so consists of the following key elements:

  1. An enum representing the performance counters we're going to have. Each counter will have a corresponding member in this enum, future counters will be added here as well.
  2. A set of attributes to decorate the above mentioned enum and provide a declarative way of conveying counter metadata.
  3. Some extension methods to alleviate metadata retrieval and make things cleaner.
  4. A class tying it all up in a neat API.
Down to work.

The attributes look like so:

Which makes your counters enum to look like so:

Now we add some extension methods to easily extract relevant information from the counters enum:

And, tie it all up in a neat API:

The grand finale looks like so:



This mechanism has some nice benefits:

  • Adding a new counter basically boils down to adding a new member to the enum (and decorating it accordingly). Since all enum members are iterated over automatically, it will be added to your category with no further effort on your side. 
  • All information pertaining to a particular counter is grouped together and is thus easily conveyed to the reader (no more constants representing counter names scattered all around, no more "wait, I can see the name but what was this counter's type again?").
  • With further work it can be leveraged into an infrastructural module applicable to any client system (which is not the case at the moment, since the enum is hard-coded with particular client's counters, making it unusable for other clients out of the box) - see the epilogue for more details.


Epilogue
This mechanism can be further improved by eliminating the coupling to a particular enum (i.e., to a particular client), and basically turned into a generic infrastructure component. The keen reader may have noticed that the extension methods are defined on the counters enum, which is client specific - not a fun fact at all.

The direction I had in mind was turning the enum into an interface with get properties decorated pretty much same manner as the current enum. Using reflection we could have a mapping between the property names and actual counter instances. Then we could use castel's DictionaryAdapter to implement that interface and have an object with actual properties which use an underlying mapping (string => counter) for the get / set functionality. The extension methods would be defined on a marker interface (i.e., an empty interface), so that any interfaces down the hierarchy could get them for free. This should allow for any client to define an interface deriving from this marker interface, define its own properties, and get all the perks we've mentioned right out of the box.

So how bout them apples?

Comments

Popular posts from this blog

Sending out Storm metrics

There are a few posts talking about Storm's metrics mechanism, among which you can find Michael Noll's postJason Trost's post and the storm-metrics-statsd github project, and last but not least (or is it?)  Storm's documentation.

While all of the above provide a decent amount of information, and one is definitely encouraged to read them all before proceeding, it feels like in order to get the full picture one needs to combine them all, and even then a few bits and pieces are left missing. It is these missing bits I'll be rambling about in this post.

Dependency Injection - The good, the bad and the ugly

The Good
Dependency injection (DI, a.k.a IoC - inversion of control) is a well known technique to increase software modularity by reducing coupling between modules. To provide the benefits of DI, numerous DI frameworks have arisen (Spring, Guice, Castle Windsor, etc.) all of which essentially give you "DI capabilities" right out of the box (these frameworks tend to provide a whole lot more than just "DI capabilities", but that's not really relevant to the point I'm about to make). Now, to remove the quotes around "DI capabilities", let's define it as a DI container - a sack of objects you can manipulate using a provided API in order to wire these objects together into an object graph that makes up your application.

I've worked on quite a few projects employing Spring, so it will be my framework of reference throughout the rest of the post, but the principles and morals apply just the same.