Using Custom Performance Counters


In Chapter 5, you saw how to use the Performance Monitor utility and the builtin .NET performance counters to monitor various performance aspects of your application. Now you're going to expand on this by looking at building your own customized performance counters to measure parts of your application that Windows normally knows nothing about. In order to do this successfully, you need to learn some terminology and how the performance objects relate to each other.

A performance counter is what Windows uses to collect performance data on various system and application resources. For example, a performance counter might monitor a physical object such as the CPU or memory, a system object such as a process or thread, or an application object such as a page request or user . In Visual Studio and .NET in general, these monitored objects are known as categories . To confuse matters even further, categories can be divided into sub-categories, referred to in the documentation as instances .

This is perhaps easier to understand with an example. Open the Visual Studio Server Explorer window, and under Servers on your local machine, select Performance Counters. Surprisingly enough, this gives you a list of performance counters, including the Elapsed Time counter when you expand the Process node. After you select the Elapsed Time performance counter, you're presented with a list of instances including Idle (the elapsed time spent in the Idle process) and System (the elapsed time spent in the System process). Although the Server Explorer doesn't show it, these two instances are part of the Process category. So the relationship between performance counters, categories, and instances looks like Table 6-2.

Table 6-2: The Relationship Between Counters, Categories, and Instances

CATEGORY: PROCESS

 

Instance: Idle

Instance: System

Counter: Elapsed Time

Counter: Elapsed Time

Once you've got your head around the terminology and relationships, the next step is to understand the different types of custom performance counters available to you, and how to create and manipulate these counters both at design time and within your code. To do this, I'm going to measure various aspects of two different sorting algorithms.

Creating Custom Performance Counters

The first task is to create several performance counters and add them to a new custom category. This new category is going to deal with performance data relating to the performance of various sorting algorithms. Each of the sorting algorithms will correspond to an instance of the new category. Table 6-3 shows the relationships of the performance objects that will form the basis of this example. The first performance counter is the number of items in a list that will be sorted. The second counter is the maximum value allowed for each item in the list. The final counter measures how many steps each of the sorting algorithms takes when sorting the list under different starting conditions as measured by the first two counters.

Table 6-3: Sorting Category and Related Counters and Instances

CATEGORY: SORTING

 

Instance: QuickSort

Instance: MagicSort

Counter: Number of items

Counter: Number of items

Counter: Maximum item value

Counter: Maximum item value

Counter: Number of sort steps

Counter: Number of sort steps

Although the program will only investigate the performance of the two sorting algorithms mentioned in Table 6-3, each of the many other sorting algorithms available would constitute another instance of the Sorting category. The idea for each sort algorithm is to measure the effect that changing the first two counters has on the third counter. Listing 6-24 shows how to create the three performance counters and the performance category that contains them. Notice that this is a once-only task; once you create the performance category and its counters, these are persistent across sessions (unless they're deleted). Therefore, you should always check that the category doesn't already exist before you create it.

Listing 6-24. Creating the Performance Category and Counters
start example
 Imports System.Diagnostics If PerformanceCounterCategory.Exists("Sorting") = False Then  'Create the three performance counters  Dim cntrNumberOfItems As New CounterCreationData("NumberOfItems", _ "Tracks the number of items to be sorted", _ PerformanceCounterType.NumberOfItems32)      Dim cntrMaxItemValue As New CounterCreationData("MaxItemValue", _ "Tracks the maximum value in items to be sorted", _ PerformanceCounterType.NumberOfItems32)      Dim cntrNumberOfSortSteps As New CounterCreationData("NumberOfSortSteps", _ "Tracks the number of steps needed to sort a list", _ PerformanceCounterType.NumberOfItems32)  'Set up performance counter collection  Dim SortingCounters As New CounterCreationDataCollection()      With SortingCounters            .Add(cntrNumberOfItems)            .Add(cntrMaxItemValue)            .Add(cntrNumberOfSortSteps)      End With  'Create the performance category and pass the collection to it.  PerformanceCounterCategory.Create("Sorting", _ "This category deals with sorting algorithm performance", SortingCounters) End If 
end example
 

In addition to using code to create performance objects, you can create performance objects at design time by using Visual Studio's Server Explorer. Just select Performance Counters under Servers on your local machine and add the required counters and categories.

Manipulating Performance Counter Instances

Once you've created your counters and categories, you obviously need to be able to update them from within your program. In this specific example, I want to create an instance of each performance counter before starting a sort and then update the NumberOfSortSteps counter during the sort. Listing 6-25 shows the creation and initialization of the performance counter components that manipulate each of the performance counter instances during a MagicSort . The PerformanceCounter component is, in my humble opinion, badly misnamed. It's not a performance counter at all ”it's a component with which you can manipulate a performance counter. This subtle distinction is rather annoying and a potential source of confusion.

But moving on to Listing 6-25, you can see that setting an instance name on a PerformanceCounter component creates a new instance, in this case for a MagicSort . If the code was doing a QuickSort instead, that's how the instance would be named. Then the performance counter instance represented by each PerformanceCounter component (I told you it was confusing) is initialized to its starting value.

Listing 6-25. Initialization of Each Performance Counter Instance
start example
 Dim NumItems As New PerformanceCounter("Sorting", "NumberOfItems", False)  'Upper bound of list to be sorted  NumItems.InstanceName = "MagicSort" NumItems.RawValue = ListToSort.GetUpperBound(0)  'Maximum data value in list to be sorted  Dim MaxValue As New PerformanceCounter("Sorting", "MaxItemValue", False) MaxValue.InstanceName = "MagicSort" MaxValue.RawValue = MaxValueInList  'The number of steps that the sorting algorithm will take 'This will be incremented by each step of the sort  Dim SortSteps As New PerformanceCounter("Sorting", "NumberOfSortSteps", False) SortSteps.InstanceName = "MagicSort" SortSteps.RawValue = 0 
end example
 

Running the program starts several MagicSorts followed by several Quick-Sorts , each with a different set of starting conditions. If you start the Performance Monitor and then monitor these performance counters as described in Chapter 5, you can see the effects that the different starting conditions have on the efficiency of the two sorting algorithms. Notice how the much-lauded QuickSort is usually unable to match the MagicSort unless the starting conditions are rather extreme.

If you want to extend this program, you could consider adding a procedure to perform each of the other sorting algorithms and then creating performance counter instances to monitor each of these algorithms as well. You might also wish to perform some more sophisticated performance measurements. The PerformanceCounterType enumeration that you specify during the creation of a performance counter contains some very useful types of measurement that you can use to do quite complex monitoring of your applications.




Comprehensive VB .NET Debugging
Comprehensive VB .NET Debugging
ISBN: 1590590503
EAN: 2147483647
Year: 2003
Pages: 160
Authors: Mark Pearce

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net