Create Custom Performance Counters
Create Custom Performance Counters
Custom performance counters enable you to extract meaningful performance and business logic data out of your ASP.NET Web applications. With the .NET Framework, you can add your own custom performance counter categories easily. You can also add performance counters to help you track just about anything going on in your Web application, including business logic. In this column, I'll show you how to create two different custom performance counters. The first one monitors the total number of items sold by a fictional online store, XYZ Products. The second monitors the average number of sales per second processed by XYZ Products.
Good system administrators are familiar with the useful information exposed by the Windows Performance Counter viewer. You can use performance counters to monitor a server's health, as well as its corresponding applications and network interactions. Some of the more popular performance counters are for processor and memory usage, simultaneous connections, throughput and response time, SQL Server performance, and Active Server Pages (ASP) and ASP.NET performance. Prior to the .NET Framework, you had to make complex API calls to interact with Windows performance counters; ASP.NET makes this process much easier.
Start creating your performance counters by developing a new ASP.NET Web application project in Visual Studio .NET. (This article uses C#, but you can port the code to Visual Basic .NET easily.) Name the project PerformanceCounterSample, open the global.asax file, and set a reference to the System.Diagnostics namespace at the top.
You need to create your custom performance counters before you can manipulate them. Create them in the Application_Start event, so you can be sure they're available when you need them (see Listing 1). The performance counters you create can survive an ASP.NET application shutdown, so first you should check to see whether the performance counter category you want to create exists already. Use the Exists method of the PerformanceCounterCategory class to verify that you actually need to create your custom performance counters.
Assemble a Counter Collection
You can't add any performance counters to a category once you've created it, so first you need to assemble a collection of performance counters. Do this by creating an instance of the CounterCreationDataCollection class. Next, create two custom performance counters. You'll use the first counter, Items Sold, to track the total quantity of items sold by XYZ Products. Performance counters can be one of many different types, depending on the type of data they monitor. Because Items Sold is a simple counter, use the PerformanceCounterType enumeration's NumberOfItems32 member. If you suspect this counter could get large, you could alternatively use the NumberOfItems64 member.
The second performance counter, Sales per Second, tracks the average number of sales processed every second. This is a more time-sensitive performance counter, so use the PerformanceCounterType enumeration's RateOfCountsPerSecond32 member. There's also a RateOfCountsPerSecond64 option for extremely high-volume, time-sensitive performance counters. The final step is to create your custom performance counters physically by passing the CounterCreationDataCollection object you just created to the PerformanceCounterCategory class's Create method.
Now that you've got your performance counters set up, build a simple Web form to simulate sales at the XYZ Products online store. Change the name of the default Web form in your ASP.NET Web application to SalesPanel.aspx. Add a few standard ASP.NET server controls to your Web form (see Figure 1). Then open up the code-behind class window for the Web form, and again set a reference to the System.Diagnostics namespace at the top. The button server control's Click event contains the code to manipulate your custom performance counters (see Listing 2). Obtain a reference to your custom performance counter by creating an instance of the PerformanceCounter class.
Next, pass in the category name XYZ Products, the performance counter name (Items Sold and Sales per Second, respectively), and "false" for the third parameter. The third parameter is important, because if you use an overloaded version of the constructor that doesn't include this parameter, then your PerformanceCounter instance will be read-only and you won't be able to increment it. Use the itemsSoldCounter object's IncrementBy method to increase the Items Sold performance counter by the quantity specified in the "quantity" TextBox server control. You can use the simpler Increment method on the salesPerSecond object, because you're increasing it by only one item at a time. You can delete both of the performance categories in the XYZ Products category easily with this code:
See Counters in Action
You can observe your custom performance counters in action by opening the standard performance counter viewer. An easy way to do this is to click on Start | Run, then type perfmon in the Run box and click on the OK button. Once open, click on the plus sign button located on the toolbar above the right-hand pane to open the Add Counters dialog box. Click on the Performance Object dropdown box and select the XYZ Products option. Your Items Sold and Sales per Second counters should now appear in the box below. Select them both while holding the Shift key and clicking on the Add button, then on the Close button. If you run your ASP.NET Web application in Visual Studio .NET and click on the Record Sale button a few times, you should see your performance counters change in the performance counter viewer (see Figure 2).
This is far from a complete tutorial on the performance counter capabilities of the .NET Framework. Indeed, you could almost write an entire book on the subject. You might want to explore the singular performance counter overloaded version of the PerformanceCounterCategory class's Create method, and review some of the methods by which you can read and display performance counter data in the browser. As an example, you can obtain the current value of the Items Sold performance counter using this code:
PerformanceCounter pc = new
long pcValue = pc.RawValue;
Overloaded versions of each of the method calls in this article control performance counters on remote machines, enabling you to aggregate data from multiple servers in a Web farm. Note, however, that this requires an account with administrator privileges.