Wednesday, September 3, 2008

Measure your Application Performance with Performance Counters



The counter is the mechanism by which performance data is collected. It is that part of a modern microprocessor that measures and gathers performance-relevant events of the microprocessor without affecting the performance of a program. The registry stores the names of all the counters, each of which is related to a specific area of system functionality. Examples include a processor's busy time, memory usage, or the number of bytes received over a network connection.

Windows uses performance counters to collect and present performance data from running processes. Windows itself provides hundreds of performance counters, each monitoring a specific aspect of your system, from CPU utilization to network traffic. In addition, other applications such as SQL Server or Exchange publish their own custom performance counters that integrate into the Windows performance monitoring system.

Windows performance counters allow your applications and components to publish, capture, and analyze the performance data that applications, services, and drivers provide. You can use this information to determine system bottlenecks, and fine-tune system and application performance.

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. You might also use a performance counter to track the number of orders processed per second or the number of users currently connected to the system.

Categories

The counter information must include the category, or performance object, that the counter measures data for. A computer's categories include physical components, such as processors, disks, and memory. There are also system categories, such as processes and threads. Each category is related to a functional element within the computer and has a set of standard counters assigned to it.

Performance Counter Types

Different performance counter types are available, covering different performance interests. They range from counts to those which calculate averages. Some of the performance counter types are for special situations only, but the following list contains the most common types you will normally use:




PurposeCounter TypeExample
Maintain a simple count of items, operations, and so on.NumberofItems32You might use this counter type to track the number of transactions executed as a 32-bit number.
Maintain a simple count with a higher capacityNumberofItems64You might use this counter type to track number of transactions executed for a
site that experiences very high volume; stored as a 64-bit number.
Track the rate per second of an item or operationRateOfCountsPerSecond32
You might use this counter type to track number of transactions executed per
second on a retail site; stored as a 32-bit number.
Track the rate per second with a higher capacityRateOfCountsPerSecond64You might use this counter type to track the number of transactions executed 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 number of a transaction takes to be processed; stored as a 32-bit number.


Creation and Setup of Performance Counters

There are two ways by which we can create Performance Counters: through VS.NET Server Explorer or programmatically. Creating performance counters using the Server-Explorer is much easier than doing it by code, but on production machines, you might not be able to install Visual Studio .NET to take advantage of this feature.

1) Using Server-Explorer

The simplest way to set up performance categories and counters is by using Server-Explorer integrated within Visual Studio .NET that ships with Server Explorer (Enterprise Architect, Enterprise Developer, or Professional).

Normally, you will find it at left side toolbar where you also have your Toolbox. If you don't see it then, make Server Explorer visible. Press Ctrl-Alt-S to make it active if it isn't currently being displayed. OR direct to the "View" menu and select the "Server-Explorer" option.

Under the Servers node, locate and expand the tree for the computer that will host the performance counters. Expand the Performance Counters node. Figure 1 shows the performance counters configured on a machine.




Figure 1: The Visual Studio .NET Server Explorer will display the list of all performance counters registered on a particular machine. Server Explorer makes it easy to add custom performance counters to the current list of counters.

To add your own performance counter, you will first create a new category. A category is typically the name of the application that will publish the performance data, although you may wish to use multiple categories for larger systems. Right click on the Performance Counters node and select Create New Category. This will launch the Performance Counter Builder dialog box shown in Figure 2.







Figure 2: The Performance Counter Builder will allow you to create new performance counters or edit existing ones.

Now create a category say ‘SoftChamps’ and add a new counter ‘Total number of operations executed’ as shown below. Add more counters by clicking the ‘New’ button.



Figure 3: SoftChamps category is created and counters are added

Click OK and you've created the performance counters and registered them on your machine.

You can also right-click on a category and select "Show category" to add some more
counters to any existing category.

In short to create counters,

  • 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.



2) Creating Programmatically

You can instrument your code with custom performance counters. .NET Framework classes provide rich set of APIs which can help developer to create custom counters with relative ease.

The System.Diagnostics namespace provides access to the performance counter libraries.

  • PerformanceCounterCategory
    – Represents a performance object, which defines a category of performance counters. Can be used to do operations on a performance category (Create, Delete, Exists, etc).

  • CounterCreationDataCollection
    - Provides a strongly typed collection of
    CounterCreationData objects which is used to create counters for a category.
  • CounterCreationData
    - Defines the counter type, name, and Help string for a custom counter.

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

  • Each counter is uniquely identified through its name and its location. In the same way that a
    file path includes a drive, a directory, one or more subdirectories, and a file name, counter information consists of four elements: the computer, the category, the category instance, and the counter name.

  • 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.

  • When creating performance counters and/or categories by code, you must ensure that the user running the code must have the proper administrative rights. This might be a problem when using performance counters in Web Applications because the ASP.NET user does not have them. Hence you should create your custom performance counters outside ASP.NET, by using either a console application or Microsoft Visual Studio® .NET Server Explorer.
  • 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.

Creating a Single Performance Counter Using PerformanceCounterCategory

If you only need to create a single counter, you can use PerformanceCounterCategory.Create
to do so.

public static PerformanceCounterCategory Create (string categoryName,string categoryHelp,PerformanceCounterCategoryType categoryType, string counterName, string counterHelp)

Parameters

categoryName

The name of the custom performance counter category to create and register with the system.

categoryHelp

A description of the custom category.

categoryType

One of the PerformanceCounterCategoryType values specifying whether the category is MultiInstance, SingleInstance, or Unknown.

counterName

The name of a new counter to create as part of the new category.

counterHelp

A description of the counter that is associated with the new custom category.

Return Value

A PerformanceCounterCategory that is associated with the new system category, or performance object.

Example



if (!PerformanceCounterCategory.Exists("SoftChamps"))

PerformanceCounterCategory.Create("SoftChamps","SoftChamps Operations",
PerformanceCounterCategoryType.SingleInstance,
"Number of operations", "Total
number of operations executed"
);

Remarks

The categoryType parameter specifies whether the performance counter category is single-instance or multi-instance. By default, a category is single-instance when it is created and becomes multi-instance when another instance is added. Categories are created when an application is setup, and instances are added at runtime. In .NET Framework 1.0 and 1.1 it is not necessary to know if a performance counter category is multi-instance or single-instance. In the Microsoft .NET Framework version 2.0 the PerformanceCounterCategoryType enumeration is used to indicate whether a performance counter can have
multiple instances.



Use the Create method of the PerformanceCounterCategory class to create a performance
counter category and a single counter at the same time.



Creating Multiple Performance Counters Using CounterCreationDataCollection

If you need to create multiple counters, you can use a CounterCreationDataCollection to programmatically create the custom counter(s) and category. This technique enables you to create the category and multiple counters at the same time.


  • To create a new performance category, first create a System.Diagnostics.CounterCreationDataCollection to hold the information about the counters.
  • Example

    CounterCreationDataCollection
    counters =
    new CounterCreationDataCollection();


  • Then you create for each counter, one System.Diagnostics.CounterCreationData instance, and add it to the collection.

Example

CounterCreationData totalTransactions = new CounterCreationData();

totalTransactions.CounterName = "no of transactions executed";

totalTransactions.CounterHelp = "Total number of transactions executed";

totalTransactions.CounterType = PerformanceCounterType.NumberOfItems64;

counters.Add(totalTransactions);

  • Use the System.Diagnostics.PerformanceCategory.Create method to create category and all related counters stored in the collection.

public static PerformanceCounterCategory Create (

string categoryName,

string categoryHelp,

PerformanceCounterCategoryType
categoryType,

CounterCreationDataCollection
counterData

)

Parameters

categoryName


    The name of the custom performance counter category to create and register with the system.

categoryHelp

    A description of the custom category.

categoryType

counterData

Return Value

    Example

    PerformanceCounterCategory.Create("SCCategory", "SoftChamps
    Sample"
    , PerformanceCounterCategoryType.SingleInstance,
    counters);

Remarks

The categoryType parameter specifies whether the performance counter category is single-instance or multi-instance. By default, a category is single-instance when it is created and becomes multi-instance when another instance is added. Categories are created when an application is setup, and instances are added at runtime. In .NET Framework 1.0 and 1.1 it is not necessary to know if a performance counter category is multi-instance or single-instance. In the Microsoft .NET Framework version 2.0 the PerformanceCounterCategoryType enumeration is used to indicate whether a performance counter can have multiple instances.



A complete sample

if
(!
PerformanceCounterCategory.Exists("SCCategory"))

{

CounterCreationDataCollection counters = new CounterCreationDataCollection();

CounterCreationData totalTransactions = new CounterCreationData();

totalTransactions.CounterName = "no of transactions executed";

totalTransactions.CounterHelp = "Total number of transactions executed";

totalTransactions.CounterType = PerformanceCounterType.NumberOfItems64;

counters.Add(totalTransactions);

CounterCreationData transactionsPerSecond = new CounterCreationData();



transactionsPerSecond.CounterName = "no of transactions executed per sec";

transactionsPerSecond.CounterHelp = "Number of transactions executed per second";

transactionsPerSecond.CounterType = PerformanceCounterType.RateOfCountsPerSecond64;

counters.Add(transactionsPerSecond);

PerformanceCounterCategory.Create("SCCategory", "SoftChamps
Sample"
, PerformanceCounterCategoryType.SingleInstance, counters);



}



This is how the counters that are added look in the Server explorer.





Figure 4: Custom Counters added in server explorer

Finally to create a new category and add some performance counters to it, you must:


  • See if the category already exists (PerformanceCounterCategory.Exists()).

  • Create a CounterCreationDataCollection and add some CounterCreationData to it.

  • Create the category (PerformanceCounterCategory.Create()).

Writing to Performance Counters



After installing performance counters, you usually want to use them to monitor performance. Therefore, you can use the System.Diagnostics.PerformanceCounter class. The difference between System.Diagnostics.CounterCreationData and System.Diagnostics.PerformanceCounter is that System.Diagnostics.CounterCreationData physically adds a performance counter to a category on your local machine,
while System.Diagnostics.PerformanceCounter is used to create an instance of a performance counter and to change performance values.

Instantiate Performance Counters

To write to a performance counter, create an instance of the PerformanceCounter class, set the CategoryName, CounterName and, optionally, InstanceName or MachineName properties, and then call the IncrementBy, Increment, or Decrement methods.

The properties that need to be set are given below:

  • CategoryName - Gets or sets the name of the performance counter category for this performance counter.

  • CounterName - Gets or sets the name of the performance counter that is associated with this PerformanceCounter instance.

  • CounterHelp - Gets the description for this performance counter.

  • MachineName - Gets or sets the computer name for this performance counter ("." is the
    local machine).

  • InstanceName - Gets or sets an instance name for this performance counter.

  • ReadOnly - Gets or sets a value indicating whether this PerformanceCounter instance is in read-only mode; as we want to write performance data, we mark it as false.
  • Example

    _TotalTransactions = new PerformanceCounter();

_TotalTransactions.CategoryName = "SCCategory";

_TotalTransactions.CounterName = "no of transactions executed";

_TotalTransactions.MachineName = ".";

_TotalTransactions.ReadOnly = false;

_TotalTransactions.RawValue = 0;



_TransactionsPerSecond = new PerformanceCounter();

_TransactionsPerSecond.CategoryName = "SCCategory";

_TransactionsPerSecond.CounterName = "no of transactions executed per sec";

_TransactionsPerSecond.MachineName = ".";

_TransactionsPerSecond.ReadOnly = false;

_TransactionsPerSecond.RawValue = 0;



Changing performance Counter Values



You can set a counter's value either by incrementing it with the PerformanceCounter.Increment method or by setting it to a specific value by calling PerformanceCounter.RawValue.

The following are the methods on a System.Diagnostics.PerformanceCounter that will help to
write to performance counters:



  • Increment - Increments the associated performance counter by one through an efficient atomic operation.

  • IncrementBy - Increments or decrements the value of the associated performance counter by a specified amount through an efficient atomic operation.

  • Decrement - Decrements the associated performance counter by one through an efficient atomic operation.

  • RawValue - Gets or sets the raw, or uncalculated, value of this counter.

Example

_TotalTransactions.Increment();

_TransactionsPerSecond.Increment();

We have seen how to install and instantiate counters. Now we will look at the counter that
will measure the average.

Performance Counters for measuring Average

An average counter measures the time it takes, on average, to complete a process or operation. Counters of this type display a ratio of the total elapsed time of the sample interval to the number of processes or operations completed during that time. This counter type measures time in ticks of the system clock.

Associated with each average counter is a base counter that tracks the number of samples involved. It is important to know that the associated base counter always must follow the counter which will monitor average!

Example

CounterCreationData averageTime = new CounterCreationData();

averageTime.CounterName = "average time per transaction";

averageTime.CounterHelp = "Average duration per transaction execution";

averageTime.CounterType = PerformanceCounterType.AverageTimer32;

counters.Add(averageTime);

//Base counter for above counter

CounterCreationData averageTimeBase = new CounterCreationData();

averageTimeBase.CounterName = "average time per transaction base";

averageTimeBase.CounterHelp = "Average duration per transaction execution base";

averageTimeBase.CounterType = PerformanceCounterType.AverageBase;

counters.Add(averageTimeBase);

Write to average counter




  • As usual first step will be to instantiate the counter.

Example


    _AverageTime = new PerformanceCounter();

    _AverageTime.CategoryName = "SCCategory";

    _AverageTime.CounterName = "average time per
    transaction"
    ;

    _AverageTime.MachineName = ".";

    _AverageTime.ReadOnly = false;

    _AverageTime.RawValue = 0;

    _AverageTimeBase = new PerformanceCounter();

    _AverageTimeBase.CategoryName = "SCCategory";

    _AverageTimeBase.CounterName = "average time per transaction base";

    _AverageTimeBase.MachineName = ".";

    _AverageTimeBase.ReadOnly = false;

    _AverageTimeBase.RawValue = 0;

  • The next step will be increment the counter

Example

    _AverageTime.IncrementBy(ticks); // increment the timer
    by the time cost of the transaction

    _AverageTimeBase.Increment(); // increment base counter
    only by 1

While the counter of type PerformanceCounterType.AverageTimer32 is incremented by the time elapsed between two calls, the base counter - of type PerformanceCounterType.AverageBase - is incremented by 1 for each operation taken.

According to .NET documentation for PerformanceCounterType.AverageTimer32 the Formula is (N1 -N0)/(B1 -B0), where N1 and N0 are performance counter readings, and the B 1 and B 0 are their corresponding AverageBase values. Thus, the numerator represents the numbers of items processed during the sample interval, and the denominator represents the number of operations completed during the sample interval.

To measure N1 and N0, we can use System.DateTime.Now.Ticks

Example:



startTime = DateTime.Now.Ticks;

System.Threading.Thread.Sleep(interval.Next(500));

long ticks = DateTime.Now.Ticks - startTime;

Use ticks to increment the PerformanceCounterType.AverageTimer32 counter.

But for more accurate results it is better you use QueryPerformanceCounter() method
via InterOp.

Example:

/// <summary>

/// Imports the <code>QueryPerformanceFrequency</code> method into the class.
The method is used to measure the current

/// tickcount of the system.

/// </summary>

/// <param
name="ticks">
current
tick count
</param>

[DllImport("Kernel32.dll")]

public static extern void QueryPerformanceCounter(ref long ticks);

The extern modifier is used to declare a method that is implemented externally. A common use of the extern modifier is with the DllImport attribute when using Interop services to call into unmanaged code; in this case, the method must also be declared as static, as shown above.

Further the code given below will be used to increment the average counter.

long startTime = 0;

long endTime = 0;

QueryPerformanceCounter(ref startTime);

System.Threading.Thread.Sleep(rand.Next(400));

// measure ending time

QueryPerformanceCounter(ref
endTime);

long ticks = endTime - startTime;

Use ticks to increment the PerformanceCounterType.AverageTimer32 counter.

Performance Monitor

The performance monitor, or system monitor, is a utility used to track a range of processes and give a real time graphical display of the results, on a Windows system. (I am presently using Windows 2003) This tool can be used to assist you with the planning of upgrades, tracking of processes that need to be optimized, monitoring results of tuning and configuration scenarios, and the understanding of a workload and its effect on resource usage to identify bottlenecks.

It can be opened by navigating to the performance icon in the administrative tools folder in the control panel, from the start menu or by typing perfmon.msc in the run box.

After you have launched Perfmon, you must select a target system, or computer, to monitor. This system can be the localhost from which you launched Perfmon or another Windows system on the local network. Because of the overhead associated with running Perfmon, it is recommended that Perfmon run on a remote computer while scrutinizing production servers for performance issues across a network. To select a system, click on the plus sign icon in the Perfmon toolbar. This action invokes a network browser showing localhost as the default monitoring target.

After you have selected the system you wish to monitor, choose an object, or subsystem, to monitor. These include such components as system, memory, network interfaces, or disk I/O subsystems. Next, choose the counters you wish to monitor.



Adding a counter

Right click anywhere on the graph and choose Add Counter.

The Add Counter box consists of the following options:


  • Computer: The source system of the object. You can choose to select the local computer or another computer on your network - type \\computer_name in the appropriate box.
  • Object: The subsystem of interest. This refers to the virtual part of the computer that you want to monitor. Memory, Processor or Network Interface, for example.
  • Counter: The aspect of performance of interest. This refers to what parts of the object you want to monitor - they differ depending on the object.
  • Instance: The specific object to be measured when multiple objects of the same type exist on a single system. For example, if you go to the Process performance object, the instances list will display all the active processes on the specified computer.




Figure 5:
The above image shows the Add Counters window.

From the Performance Object dropdown select SCCategory, click ‘Add’ to add the counters.





 

Figure 6: Add the custom counters to the monitor

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.

2 comments:

Ravindran Keshavan said...

Hi Steve.. Good article.. actually I'm trying to access the counters using WMI ...

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set objRefresher = CreateObject("WbemScripting.SWbemRefresher")

Set colItems = objRefresher.AddEnum _
(objWMIService, "CustomAppCategory").objectSet

for this line I get invalid class...Since I have created a Custom category, I'm unable to determine the class name.. You have any idea on this?

Nilesh said...

Hi Steve,
i m using using System.Diagnostics.PerformanceData;
using System.Diagnostics;
to get performance counter details

When i am passing remote machine name in the parameter its giving me exception "invalid path name" for eg if my remote machine name is "abc"
then i taking this parametere from user by text box so if user enters "\abc" so its giving me exception but if i hardcoaded the same thing in machine name parametere than its working fine
so is there any way around or any other alternative to take remote machine name from user

See Below is my code

PerformanceCounterCategory[] arrCategories =
PerformanceCounterCategory.GetCategories(textbox1.text) /// it will throw an exception


if i do like this

PerformanceCounterCategory[] arrCategories =
PerformanceCounterCategory.GetCategories("\abc"); /// its working fine here


So please provide me solution asap.


Thanks in Advance!!


Nilesh