This post discusses .NET Performance counters and their use in monitoring resource utilization.
.NET provides various classes for monitoring the resource utilization of the CPU, memory, disk and network cards. Sadly, the documentation is particularly vague with respect to what can be monitored and how this can be done. This article describes basic use of performance counters and gives a sample class (see end of text) which displays some of these on the command line.
The PerformanceCounter class is used as the basis for all monitoring. This can be set up as follows:
private PerformanceCounter pcounter = new PerformanceCounter(categoryName, counterName, instanceName);
This constructor takes three parameters:
- categoryName refers to the type of resource to be monitored. The following values are permissible on all machines (you can also create your own custom counters):
- LogicalDisk / PhysicalDisk
- Network Interface
- counterName is the name of a specific counter within that category. For example, if monitoring the processor
% Processor Timespecifies that we want to look at the percentage of time the processor was busy during the sample period. The following pages list counters for each of the resources provided by Microsoft:
- InstanceName specifies the instance of the resource being monitored. For example, when monitoring disk utilization you may want to specify which drive is to be monitored. Alternatively, to monitor all instances just enter
private PerformanceCounter processorcounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
Measures the percentage of time the processor was busy during the sample period.
private PerformanceCounter memcounter = new PerformanceCounter("Memory", "Available MBytes");
Shows the amount of physical memory available to the processor (in megabytes).
private PerformanceCounter diskcounter = new PerformanceCounter("LogicalDisk", "% Free Space", "_Total");
Shows the percentage of free disk space (over all logical disks).
private PerformanceCounter bandwidthcounter = new PerformanceCounter("Network Interface", "Current Bandwidth", "Intel[R] 82562V-2 10_100 Network Connection”);
An estimate of the current bandwidth of the network interface. The instanceName in this case must be the name of the network card being monitored.
If you don’t know the name of your network card the following code may be helpful. It returns a string array of all the network cards on your local machine:
PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");
String instancename = category.GetInstanceNames();
The same method can be used to find the names of logical disks or other devices on the local machine – just replace the
Network Interface string with the category of your choice.
Now that we’ve instantiated our monitors we need some method of obtaining samples. For example, the following code extracts a sample from our processor counter:
float sample = processorcounter.NextValue();
There are a number of other fields and methods that may be of interest. To get a human readable description of the counter being used use the CounterHelp field:
String counter_description = processorcounter.CounterHelp;
This article covers the basics of the PerformanceCounter class. To see it used in practise check out some of these examples: