Article Options
Recently Viewed
Premium Sponsor
Premium Sponsor

 »  Home  »  Windows Development  »  Creating Custom Performance Counters in VB.NET
Creating Custom Performance Counters in VB.NET
by Manoj G | Published  03/05/2003 | Windows Development | Rating:
Manoj G

I am a software developer working on Microsoft Technologies for about a couple of years. I have always been fascinated by Microsoft Technologies and with the advent of .NET , this fascination has reached new heights. I take a lot of interest reading technical articles and equally enjoy writing them. I really like to be called a .NET junkie and will surely try to live up to this name :)

 

View all articles by Manoj G...
Creating Custom Performance Counters in VB.NET

Introduction

Windows OS and .NET runtime provide a host of performance counters that developers and administrators can use to probe into the performance of an application. But developers will always find the need to have counters specific to their applications. For example, an accounting application can have counters like Accounts created, Transactions processed, total running balance, Number of users logged on to the application and so on.

.NET Framework classes provide rich set of APIs which can help developer to create custom counters with relative ease. In the following sections I will explain how this can be done with VB.NET.

Creating custom counter categories

All performance counters fall under specific categories. For example you have %Processor time, %User time, etc. under the Processor category. So, we would need to create our custom categories and then specify one or more counters under it. There are two ways by which we can create them: through VS.NET Server Explorer or programmatically. Let's see each of these in detail.

1. Using Server Explorer
Visual Studio.NET makes life easier here by giving us an interface to create counters at design time. Enlisted below are the steps you can follow to create the same.

  • Open the Server Explorer
  • Select Servers -> your computer name -> Performance Counters
  • Right click Performance Counters and select "Create New Category..."
  • In the dialog box, enter the name of the Category and any description you would like in the Category Description text box.
  • In the counter list builder frame click "New" to add a new Performance Counter.
  • Enter the name of the performance counter and select the Type, and any description you would like as the Counter description.
  • Click OK.
Below is a snapshot of the Performance counter builder.

2. Doing it programmatically
System.Diagnostics namespace provides classes which we can use to create and manipulate custom performance counters. Given below are the steps which we typically use for this purpose.

  1. Create a collection of type CounterCreationDataCollection.
  2. Create the counters you want to create as objects of type CounterCreationData and set their necessary properties.
  3. Add the CounterCreationData objects to the collection by calling the collection's Add method.
  4. Call the Create method on the PerformanceCounterCategory class and pass the collection to it.

'Assumes import statement for System.Diagnostics.dll
Dim CounterDatas As New System.Diagnostics.CounterCreationDataCollection()

'Create the counters and set their properties.
Dim cdCounter1 As New System.Diagnostics.CounterCreationData()
Dim cdCounter2 As New System.Diagnostics.CounterCreationData()

cdCounter1.CounterName = "Transactions Active"
cdCounter1.CounterHelp = "Indicates number of active transactions"
cdCounter1.CounterType = Diagnostics.PerformanceCounterType.NumberOfItems64
cdCounter2.CounterName = "Users Logged on"
cdCounter2.CounterHelp = "Gives the number of users logged on to the " _
    & "application"
cdCounter2.CounterType = Diagnostics.PerformanceCounterType.NumberOfItems64

'Add both counters to the collection.
CounterDatas.Add(cdCounter1)
CounterDatas.Add(cdCounter2)

'Create the category and pass the collection to it.
PerformanceCounterCategory.Create("Accounting"_
    "A set of counters for the accounting application"CounterDatas)

If you need to create a category with just one performance counter, you can use the overload of the Create method as follows:

PerformanceCounterCategory.Create("Accounting"_
    "A set of counters for the accounting application"_
    "Transactions Active","Gives number of transactions being processed")

There are a few things to consider regarding custom performance counters.

  • You cannot create custom categories and counters on remote machines.
  • Our interaction with custom counters and categories is restricted to read-only mode unless you explicitly specify otherwise. By default the counters created under server explorer are read only and under read-only mode you cannot update the value of the counter.
  • To create custom counters on the local computer you need administrative access.
  • You cannot create new counters within existing custom categories. If you need to add counters to categories that already exist, the only way you can do so is to delete the category and recreate it with all of its contents, including the new counters you want to add.
  • If you try to create a counter that already exists, an error would be thrown. You can check the existence of a counter before you create one. For example:

If Not (PerformanceCounterCategory.Exists("MyCat")) Then
    PerformanceCounterCategory.Create("MyCat""Desc""MyCtr""Desc")
End If

Performance Counter Types

Another important aspect of a performance counter is its type. In the example shown earlier, we had assumed a type NumberofItems64 without actually knowing what it is. Well, in this section I will explain the various counter types and this should give an idea as to where each type can be used. Given below is a table explaining the important counter types and where they can be used appropriately.

If You Need ToUseExample
Maintain a simple count of items, operations, and so on.NumberofItems32You might use this counter type to track the number of orders received as a 32-bit number.
Maintain a simple count with a higher capacityNumberofItems64You might use this counter type to track orders for a site that experiences very high volume; stored as a 64-bit number.
Track the amount per second of an item or operationRateOfCountsPerSecond32You might use this counter type to track the orders received per second on a retail site; stored as a 32-bit number.
Track the amount per second with a higher capacityRateOfCountsPerSecond64You might use this counter type to track the orders per second for a site that experiences very high volume; stored as a 64-bit number.
Calculate average time to perform a process or to process an itemAverageTimer32You might use this counter type to calculate the average time an order takes to be processed; stored as a 32-bit number.

Updating and reading Performance counters

Okay, now that we have an idea about performance counter categories and their types and that we have created them, let's see how this can we manipulate them in our application.

System.Diagnostics namespace provides PerformanceCounter class using which we can read and manipulate values of counters. Let's look and some of the properties and methods of this class which we can use.

Public Properties

NameDescription
CategoryNameGets or sets the name of the performance counter category for this performance counter.
CounterHelpGets the description for this performance counter.
CounterNameGets or sets the name of the performance counter that is associated with this PerformanceCounter instance.
CounterTypeGets the counter type of the associated performance counter.
InstanceNameGets or sets an instance name for this performance counter.
MachineNameGets or sets the computer name for this performance counter
RawValueGets or sets the raw, or uncalculated, value of this counter.
ReadOnlyGets or sets a value indicating whether this PerformanceCounter instance is in read-only mode.

Public Methods

NameDescription
DecrementDecrements the associated performance counter by one through an efficient atomic operation.
IncrementIncrements the associated performance counter by one through an efficient atomic operation.
IncrementByIncrements or decrements the value of the associated performance counter by a specified amount through an efficient atomic operation.
NextSampleObtains a counter sample, and returns the raw, or uncalculated, value for it.
NextValueObtains a counter sample and returns the calculated value for it.
RemoveInstanceDeletes the category instance specified by the PerformanceCounter object InstanceName property.

Now, let's see a few of them in action with a simple code snippet. Here we are incrementing a counter before beginning some processing and then decrement it back once it's over.

Dim myCounter As New PerformanceCounter("Accounting"_
    "Transactions Active"false)

myCounter.Increment()

' Start a transaction 
' <<<Do some processing>>>
' Complete transaction

myCounter.Decrement()
myCounter.Close()

Note: In the code piece shown above we programmatically created an instance of the PerformanceCounter object. In VS.NET, we can do this by just dragging an icon of from the toolbox into the designer surface.

Adding and Removing Instances

It is likely to have more than one instance of a performance object. For instance, the Processor performance object has one instance for every processor on the system.

Adding instances

You add instances by setting a raw value for the counter. If no instance exists for the counter, it will be created the first time you set the RawValue property, and all subsequent actions on the raw value are assumed to impact that instance if no other is specified. You can create additional instances by specifying a new instance name and then setting a value after it.

' Assumes the category and counter have already been created.
Dim myCounter As New System.Diagnostics.PerformanceCounter_
    "cat","counter","instance1"false)

'Set the raw value to automatically create instance1.
myCounter.RawValue = 100

'State that you will now be working with a different instance.
myCounter.InstanceName = "instance2"

'Setting the value actually creates instance2.
myCounter.RawValue = 200

Deleting Instances

You may need to remove instances dynamically in your application. For example if you have an instance for every logged on user you may need to delete an instance when the user logs off. You can delete instances by using the RemoveInstance method of the PerformanceCounter class.

Dim PerformanceCounter1 As New PerformaceCounter_
    "Accounting"," Logged on Users"false)

PerformanceCounter1.InstanceName = "Admin"
PerformanceCounter1.RemoveInstance()

Deleting a Performance counter category

Like in the case of creation, we can use the VS.NET Server Explorer to delete Performance counter categories or do it programmatically.

Using Sever Explorer

  • Locate the performance category in Server Explorer
  • Right click the category and select Delete

Doing it programmatically

  • Call the Delete method on the PerformanceCounterCategory class, specifying category to remove as a parameter.

Note: Using the above approaches, you can only delete user defined categories, not Windows-standard performance objects. We cannot delete categories on remote computers.

Adding Installers

VS.NET has a very nifty feature called Project Installers. You can add installers for several objects like custom performance counter objects. If we add installers to the project and run InstallUtil.exe against the assembly (with the /i switch), these counters get installed automatically. Likewise these counters would be automatically removed when we run Installutil.exe with a /u switch.

Adding an installer is pretty easy. Right click the object on the designer surface and select "Add Installer". You can also change the properties of the installer using the Properties pane of the Installer. These are the settings that would be applied when the assembly is installed using InstallUtil.

Conclusion

Custom performance counters are a great value addition that a development team can make to a production environment. It is definitely one of the easiest ways to monitor the health and performance of the application. The .NET Framework and VS.NET definitely makes implementation of counters a relatively simple task.

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:3.56666666666668 out of 5
 30 people have rated this page
Article Score36450
Comments    Submit Comment

Comment #1  (Posted by Sekhar on 09/09/2003)

I am trying to read the system Performance counters;
The Following is the code:
X.CategoryName = "Processor"
X.CounterName = "% Processor Time"
X.InstanceName = "_Total"

I am getting some value with X.RawValue but i don't know how to interpret that.

I am getting 0 always when i use X.Nextvalue.

Thanks in advance.
 
Comment #2  (Posted by Dave Ball on 10/22/2004)

You need to prime the next value i.e have
x.nextvalue
X.nextvalue
as the first one is always 0

I'm also having a problem with performance counters.
I have a program which takes counters and put them into a database however the program stops running aftera short period of time.i added the counters to a form by dragging them fom the server explorer is this whats causing it i.e is it running out of memory or something should i drop the connections and then recreated them. Any advice would be handy
 
Comment #3  (Posted by an unknown user on 02/28/2005)
Rating
Just a rehash of the documentation found with Visual Studio and on MSDN.
 
Comment #4  (Posted by an unknown user on 07/13/2005)
Rating
Useless, waste of computer storage
 
Comment #5  (Posted by an unknown user on 10/28/2005)
Rating
no, what is a waste is your ignorant comments..I found the article informative regardless wether it was found on msdn or not...Do you have some kind of inferiority complex thats triggered when you see these informative tutorials? Seek help, but not from MSDN: like a shrink or something.
 
Comment #6  (Posted by Eric on 10/28/2005)

What would cause a counter instance to be called "0 Unknown#1"?
Ive got from 40 to 50 of these all labeled "0 Unknown#N" where n is the number starts from zero.
It's listed under the 'Terminal Services Session' perf. object?
 
Comment #7  (Posted by an unknown user on 11/17/2005)
Rating
Nice brief article that seems very useful
 
Comment #8  (Posted by an unknown user on 12/06/2005)
Rating
For what concerns counters instances it says the same things as MSDN. Unfortunately it is a shame that it doesn't work.
 
Comment #9  (Posted by an unknown user on 09/27/2006)
Rating
Ignore all the gutless anonymouse pissants - great article !
 
Comment #10  (Posted by David Deen on 10/10/2006)
Rating
I can not believe how negative some of these cretins can be, this is a fantastic article.
 
Comment #11  (Posted by an unknown user on 03/23/2007)
Rating
Good boy... compared to the technical stuff from book self paced kit for 70536, this is a brief but very clear introduction for what the hell is this all about !
 
Comment #12  (Posted by an unknown user on 04/24/2007)
Rating
The article is well written in the sense that it explains very well what needs to be done without too much information. This is grt.
 
Comment #13  (Posted by an unknown user on 05/06/2007)
Rating
So Good.
 
Comment #14  (Posted by an unknown user on 06/08/2007)
Rating
It helped me a lot !
What would be the best way to keep trak of a Min value of a integer?

thanks
 
Comment #15  (Posted by an unknown user on 06/15/2007)
Rating
Explanation was good but I'd put the output and how it relates with any task we'd like to implement using it
 
Comment #16  (Posted by an unknown user on 08/13/2007)
Rating
the aricle is written great and was very helpfull for me. but the difference between nextValue and rawValue is still a mystery for me. could you shortly explain that for me, please?
 
Comment #17  (Posted by an unknown user on 11/18/2007)
Rating
Maybe should have mentioned that the Server Explorer isn't available in the Standard Edition of Visual Studio. Good article just the same.
 
Comment #18  (Posted by an unknown user on 11/18/2007)
Rating
Maybe should have mentioned that the Server Explorer isn't available in the Standard Edition of Visual Studio. Good article just the same.
 
Comment #19  (Posted by an unknown user on 07/20/2008)
Rating
Just what I needed thanks!
 
Comment #20  (Posted by an unknown user on 08/11/2008)
Rating
Good concise article.

The author touched on the counters being read-only by default, but didn't mention where you can specify this not to be the case...?
 
Comment #21  (Posted by an unknown user on 09/02/2009)
Rating
Does not actually explain anything useful
 
Comment #22  (Posted by an unknown user on 07/13/2010)
Rating
Good effort but I did not glean any useful information from this article.
 
Sponsored Links