Thursday, January 15, 2004

Retreiving Performance Counter Values With VB.Net

From Windows 98 on Microsoft has included performance counters in their O/S that measure all kinds of things going on in the system: memory usage, disk access, network bandwidth use, etc. Your software can access these values through the performance counters for reporting, notification of system problems, etc. I've recently finished an application which sits on a server and regularly pulls performance counter values from all of the computers on the network, alerting the network administrator if any of the values rise above of fall below values set as the acceptable range.

It's very easy to access performance counters in Visual Basic .NET. Here's how you do it:


Imports System.Diagnostics

Public Class CounterTest

Public CounterTestValue As Single

Public Sub New()

Dim counter As New PerformanceCounter("Processor", _
"% Processor Time", _
"_Total")

CounterTestValue = counter.NextValue

End Sub

End Class


---

Here's the syntax of the PerformanceCounter constructor:

New PerformanceCounter(CategoryName, CounterName, InstanceName)


---

The category name is which group of counters the counter you want belongs to (such as Processor or Memory or Thread), the counter name is the text name of a counter that is in that category. Those two things are pretty obvious.

The InstanceName is not always so obvious, because it's not always required. A counter's instances break down the counter into all of its smaller parts. For example, the Process category has a counter called "% Processor Time" that has instances for each application currently running, as well as one called "_Total" (a common instance name) which gives you the processor time of all processes. Not all counters have an instance. A few do. If a counter does not have an instance you can pass an empty string, or better yet, just use the constructor overload that does not require the instance name.

The PerformanceCounter class also has a constructor overload which takes the network id of the machine you want to get the counter from. So, for example, if I wanted to get the processor usage on a machine on the LAN called "Loris", I would change the above class like so:


Dim counter As New PerformanceCounter("Processor",
"% Processor Time",
"_Total",
"Loris")


---

It's that simple.

NOTE: Be careful when pulling performance counters from machines on the LAN running different versions of Windows. Microsoft introduced new performance counters with each new Windows version, so make sure that the counter you are able to pull from your Windows XP machine exists on that Windows 2000 box before you try it. Also, the user under which your program is running must have rights to access performance counters on other machines. It is usually best to run the program under a Domain Administrator user, as this guarantees its ability to read the counters.

To find out what performance counters are available to you, go to Control Panel -> Administrative Tools -> Performance. Right-click in the graph and select "Add Counters". There you can see a list of all of the categories and their specified counters and the instances of those counters.

TIP: Many of Microsoft's Software Packages create their own performance counters when installed. A big one is MS Sql Server, which creates dozens of counters for database administrators to use in monitoring the performance of their databases. Your software can access these as well. In addition, .NET makes it very easy to create your own performance counters. How to create your own counter will be the subject of a future blog.