Click here to Skip to main content
13,631,244 members
Click here to Skip to main content
Add your own
alternative version


35 bookmarked
Posted 18 Apr 2006
Licenced CPOL

Using Custom Attributes to Create Performance Counters

, 12 Jun 2007
Rate this:
Please Sign up or sign in to vote.
This article describes how to use custom attributes to automate performance counter and category creation.
Performance Monitor


Performance counters provide an excellent method to monitor key performance indicators for an application. Before being able to write to a performance counter, two tasks need to be completed.

  • First, the performance counter category and the contained performance counters must be created on the machine where the application is going to use them. This can only be done by a user with administrative rights.
  • Second, the application needs to create writable instances of the performance counters.

By using custom attributes (this was inspired by Duncan Edwards Jones' article about performance counters) and a helper class, we can easily perform both tasks from a single definition for each performance counter.


We recently introduced new search technology to our Web site and wanted to make sure that we get a good feeling for the performance of that search technology in the production environment. We also wanted to define thresholds for some performance indicators for the system and network monitoring tool so we can automatically raise alerts if performance drops below the threshold. Performance counters were the ideal solutions for us since they are lightweight, fast, and could easily be plugged into our monitoring tool.

For ease of use and maintenance reasons, we only wanted to define performance counters once in the code and then have the ability to use that definition to create the performance counters and categories on the machine as well as the instances in the application. Due to the application being a Web site, there was no way for the application to create the performance counters if they did not exist because it does not have administrative rights. At the same time we wanted to avoid having to create additional tools for performance counter and category creation.

Using the Custom Attributes

To associate a class with a performance counter category, simply decorate the class with the PerformanceCounterCategoryAttribute.

[PerformanceCounterCategory("Random Test", PerformanceCounterCategoryType.MultiInstance)]
class Test

To associate a PerformanceCounter class member with a performance counter, simply decorate it with the PerformanceCounterAttribute.

[PerformanceCounter("Random Rate", "", PerformanceCounterType.RateOfCountsPerSecond32)]
private static PerformanceCounter pcRandomRate;

[PerformanceCounter("Random Average", "", PerformanceCounterType.AverageCount64)]
private PerformanceCounter pcRandomAverage;
private PerformanceCounter pcRandomAverageBase;

[PerformanceCounter("Random Value", "", 
    PerformanceCounterType.NumberOfItems64, "Standard")]
private PerformanceCounter pcRandomValue;        

[PerformanceCounter("Random Value", "", 
    PerformanceCounterType.NumberOfItems64, "Inverted")]
private PerformanceCounter pcRandomInvertedValue;        

private bool usePerformanceCounters;

Note that counter types that need a base counter only have an attribute on the actual performance counter. The helper class will automatically create the base counter when needed. The helper class also assumes that the variable name for the base counter is the performance counter variable name with "Base" appended to it. The same assumption is made for the counter and base counter names.

If the performance counter category is created to support multi-instance counters and a counter does not have an instance name, the helper class uses _default as the instance name.

Declare a boolean variable that can be used to safeguard updating of performance counters in the application code.

Creating Writable Performance Counter Instances

To instantiate the performance counter for a given class, use the helper class PerformanceCounterFactory inside the constructor:

public Test()
    pcRandomRate = pcRandomAverage = pcRandomAverageBase = pcRandomValue
        = pcRandomInvertedValue 
        = null;

        // create writable performance counter instances
        usePerformanceCounters = 
            PerformanceCounterFactory.CreateCounters(typeof(Test), this);
    catch (Exception)
        usePerformanceCounters = false;

Updating Performance Counters

The performance counters can then be updated as usual from within the application code. Make sure the performance counter access is safeguarded with a boolean variable that indicates that the performance counter creation was successful.

if (usePerformanceCounters)
    // set number counter
    pcRandomValue.RawValue = r;
    pcRandomInvertedValue.RawValue = randMax - r;
    // update rate counter
    // update average counter

Installing Performance Counter Categories

The code above assumes that the performance counters and the category they belong to already exist. From the class definition and attributes, we can also create the category and performance counters by using the helper class in conjunction with an Installer and a PerformanceCounterInstaller. The following code needs to be added to the installer's constructor:

// Create a new helper class instance
PerformanceCounterFactory category = new PerformanceCounterFactory(typeof(Test));

// now add the counters to the performance counter installer
counterInstaller.CategoryName = category.Name;
counterInstaller.CategoryType = category.CategoryType;
if (category.Help != null)
    counterInstaller.CategoryHelp = category.Help;

If the performance counters for a performance counter category spread across multiple classes, use PerformanceCounterFactory.AddCounters(typeof(AdditionalTestClass)); to add them to the helper class before passing them to the PerformanceCounterInstaller.

Installing and uninstalling of performance counter categories can simply be done by running installutil with the given assembly.

To install a performance counter category and counters without using an installer, simply use the PerformanceCounterFactory constructors and the Create() method.

Points of Interest

Installers can be useful even if you do not intend to wrap them in an MSI.


  • 1.0 Initial version
  • 2.0 Migrated the code to .NET 2.0 and added support for performance counter instances


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Andreas Piefke
Web Developer
Australia Australia
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralPerformanceCounterCategory.Exists Pin
Member 422196925-Jul-08 5:33
memberMember 422196925-Jul-08 5:33 
GeneralI need your changes. Pin
jmgac26-Apr-07 12:08
memberjmgac26-Apr-07 12:08 
GeneralCounters with instances Pin
SaurweinAndreas22-Oct-06 9:49
memberSaurweinAndreas22-Oct-06 9:49 
GeneralRe: Counters with instances Pin
Andreas Piefke23-Oct-06 1:53
memberAndreas Piefke23-Oct-06 1:53 
GeneralRe: Counters with instances Pin
SteveC-A922-May-08 6:56
memberSteveC-A922-May-08 6:56 
GeneralRe: Counters with instances Pin
Andreas Piefke23-May-08 2:36
memberAndreas Piefke23-May-08 2:36 
GeneralRe: Counters with instances Pin
Uwe Keim13-Feb-07 2:54
sitebuilderUwe Keim13-Feb-07 2:54 
GeneralRe: Counters with instances Pin
Madmaximus15-Aug-07 4:20
memberMadmaximus15-Aug-07 4:20 
GeneralSmall fix for derived classes Pin
Red_F29-Aug-06 2:40
memberRed_F29-Aug-06 2:40 
GeneralWell done Pin
mhrushka6-Jun-06 8:47
membermhrushka6-Jun-06 8:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.180712.1 | Last Updated 12 Jun 2007
Article Copyright 2006 by Andreas Piefke
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid