Monitor Your Applications With Vista’s Performance Logs and Alerts

Monitor Your Applications With Vista’s Performance Logs and Alerts

he Windows Reliability and Performance Monitor (RPM) (see Figure 1) is a new application in Windows Vista that unifies the approach to monitoring real-time and historical reliability and performance data. The Performance Logs and Alerts (PLA) API gives you programmatic access to features in the RPM and is also new to Windows Vista.

Figure 1. Reliability and Performance Monitor: One view of the RPM application showing various monitoring capabilities. The PLA API gives you programmatic access to its capabilities.

Author’s Note: RPM integrates three previously separate applications: Server Performance Advisor, System Monitor, and Performance Logs and Alerts. Be careful not to confuse the obsolete Performance Logs and Alerts application with the new Performance Logs and Alerts API.

In this article I’ll use the RPM as a developer’s tool for the PLA API. Using the RPM makes it easier to understand the concepts in the PLA API, but it isn’t required to write PLA-enabled applications.

The RPM is designed as an integrated application for system administrators; the PLA API is designed for application developers to fulfill their applications’ supportability, reliability, and performance requirements.

You can follow along with the techniques shown here, and experiment as you go. The article demonstrates how to create data collector sets both with the RPM and programmatically, and discusses specific types of data collectors.

To build and run the applications shown here, you’ll need Microsoft Windows Vista and Microsoft Visual Studio 2005 with all required updates. I’ve used C# in this article, but I encourage you to use your favorite .NET language when you create PLA-enabled applications.

The PLA API isn’t exposed in the .NET Framework Class Library. To use it in managed code, launch the Visual Studio 2005 Command Prompt and then run the .NET Framework Type Library Importer tool:

   TlbImp.exe C:WindowsSystem32pla.dll

Add the generated PlaLibrary.dll assembly as a reference to your Visual Studio projects. Use the Class View window to explore the generated .NET types.

Creating a Data Collector Set with the RPM
To monitor a system’s reliability and performance you’ll need to collect data. The possible data sources fall into three general categories:

  • Performance counters in operating system code and application code
  • Trace messages generated by various events
  • Registry key values representing system configuration information

A data collector is a specific data source in one of these categories. A data collector set is a reusable group of data collectors.

Figure 2. Four “System” Data Collector Sets: Windows Vista ships with four data collector sets. Selecting a data collector from the list in the left pane displays the data collectors contained by that set in the right pane.

Consider a data collector set with two performance counter data collectors, a trace message data collector, and a registry key value data collector. You can run the data collector set to collect real-time reliability and performance data and then revisit that data later. Data collector sets are hierarchical; you can organize data collector sets into other data collector sets.

Explore the data collector sets that come with Windows Vista by launching the Reliability and Performance Monitor (simply type “reliability” in the Windows Vista Start Search text box). Expand the Data Collector Sets –> System node, and then click one of the four provided data collector sets to see its data collectors (see Figure 2).

The most robust way to create a data collector set is to use an XML template that contains information about the data collector set and its individual collectors. Windows Vista ships with predefined templates you can select in the RPM Data Collector Set wizard or load using the PLA API.

To create a user-defined data collection set in the RPM, right-click on Data Collector Sets –> User Defined and then click New –> Data Collector Set.

In this case, create a template-based data collector set with a name that indicates you created it in the RPM (see Figure 3).

Figure 3. Creating a Data Collector Set: Create your first data collector set using one of the predefined templates that ship with Windows Vista.
Figure 4. Select a Template: Select a template data collector set to see a brief description of the data it collects.
Figure 5. Provide a Location: Specify a folder in which to store the collected data.

When you click Next, you’ll get a chance to select a template. Select the System Performance template (see Figure 4).

Next, you’ll need to select or enter the location where you want to store the data. This is an important consideration when you create the data collector sets programmatically through the PLA API?you’ll want to be able to get to the data later. For this example, you can accept the default (see Figure 5).

When you click Next from the screen in Figure 5, you’ll get a screen where you can select an account under which to run the collector set, and some options that determine what the wizard does when it finishes. For this exercise, accept the account, select the option to “Open the properties for this data collector set,” and click Finish (see Figure 6). That closes the wizard and brings up the data collector set Properties dialog shown in Figure 7.

Figure 6. Create Options: The last screen of the Wizard lets you choose an account and provides three post-Wizard options for the new data collector set.
Figure 7. Setting Data Collector Set Properties: Data collector set properties include all the parameters shown here, plus additional settings for security and scheduling.

Change the description as shown in Figure 7, and then close the dialog.

Now you can expand the Data Collector Sets –> User Defined node in RPM to see your new data collector set. Right-click on the new data collector set item, and then click Save Template to export it as an XML file. You can make a few changes to the XML file and use it to create another data collector set with the PLA API. Here are a few portions of the template you just created:

            ...      A sample data collector set...      ...      DevX (Created with the PLA API)               C:perflogsDevX (Created with the PLA API)20070501-0001            ...      SYSTEM      ...               1         NT Kernel         ...                     0         Performance Counter         ...                     ...                     ...            

Data collector set templates may contain an enormous amount of information and are difficult to author from scratch, so it’s easiest to use the RPM to create data collector set templates for use in your PLA-enabled applications.

Creating a Data Collector Set with the PLA API
Creating a data collector set programmatically takes only a few lines of code when you have an appropriately configured XML template already available. You can use the template you just created as a base; modify the path variable in the code below to suit your needs:

   using PlaLibrary;      ...      // Load the XML template   string path = @"C:DevelopmentDevX.PlaDevX.Pla.Template.xml";   StreamReader reader = File.OpenText(path);   string templateXml = reader.ReadToEnd();   reader.Close();      // Create the data collector set   IDataCollectorSet collectorSet = new DataCollectorSetClass();   collectorSet.SetXml(templateXml);      // Save the data collector set for later use   string name = @"ServiceDevX (Created with the PLA API)";   collectorSet.Commit(name, null, CommitMode.plaCreateOrModify);   

Use the IDataCollectorSet.SetXml method as shown in the preceding code to configure the data collector set with an XML template. You can also configure the data collector set manually through exposed IDataCollectorSet properties, such as IDataCollectorSet.OutputLocation and IDataCollectorSet.RootPath.

Figure 8: Commit Method: Use the IDataCollectorSet.Commit method to save a collector set for later use.

The IDataCollectorSet.Commit method saves the data collector set. Here’s the syntax for a Commit call:

   IDataCollectorSet.Commit(string name,       string server, CommitMode mode);

Data collector sets you save with the Commit method will appear next to other user defined data collector sets in the RPM (see Figure 8).

The Commit method provides powerful mechanisms for deploying and reusing data collector sets through its three parameters, described in Table 1.

Table 1.IDataCollectorSet.Commit Parameters: The parameters for the Commit method provide powerful mechanisms for deploying and reusing data collector sets.
ParameterAllowed ValuesDescription
nameServiceSets created by the user; can be scheduled and set to run as anyone.
SystemRead-only sets; cannot be scheduled.
LegacySets running on operating systems prior to Vista.
SessionSpecial-purpose namespace for Event Tracing sessions.
AutosessionSpecial-purpose namespace for Event Tracing AutoLogger sessions.
serverComputer name, fully qualified domain name, IP address (IPv4 or IPv6), or null for the local computer.Computer on which to save the data collector set.
modeplaCreateNewCreates a new set; fails if it already exists.
plaModifyModifies an existing set; fails if it doesn’t already exist.
plaCreateOrModifyCreates a new set or updates it if it already exists.
plaUpdateRunningInstanceApplies new properties to the running set instance.
plaFlushTraceApplies only to sets with Event Tracing sessions.
plaValidateOnlyValidates the set’s properties.

Opening and Running Data Collector Sets
To run a data collector set in the RPM, simply right-click on it and then click Start. To examine the data collected by the set, expand the Reports –> User Defined node?either during the run or after the data collector set run completes (see Figure 9).

Figure 9. RPM Run Information: The RPM displays detailed information about data collector set runs.

Open and run a data collector set using the PLA API with the IDataCollectorSet.Query and IDataCollectorSet.start methods.

   // Open the data collector set   IDataCollectorSet collectorSet =       new DataCollectorSetClass();   string name =       @"ServiceDevX (Created with the PLA API)";   collectorSet.Query(name, null);      // Run the data collector set   collectorSet.start(false);      // Immediately report the status   Console.WriteLine(collectorSet.Status);      // Wait a moment and report the status   Thread.Sleep(TimeSpan.FromSeconds(10));   Console.WriteLine(collectorSet.Status);      // Wait another moment and report the status   Thread.Sleep(TimeSpan.FromMinutes(1));   Console.WriteLine(collectorSet.Status);   

The IDataCollectorSet.Query accepts the same name and server parameters (the first two) you passed into IDataCollectorSet.Commit. Loading a data collector set this way overwrites any parameters that were already configured on the IDataCollectorSet instance.

Data collector sets run in a separate process. Pass true to IDataCollectorSet.start to run the set synchronously, which causes the current thread to wait for the run to complete; pass false to return control to the current thread as soon as Windows queues the run.

If you run a data collector set asynchronously, you can use the IDataCollectorSet.Status property to monitor the state of the run. Table 2 lists the various status enumeration values.

Table 2. DataCollectorSetStatus Enumeration Values: The table lists the values in the DataCollectorSetStatus enumeration, along with a brief description of each.
DataCollectorSetStatus EnumerationDescription
plaStoppedNot running.
plaRunningCollecting data.
plaCompilingPerforming data management and compiling data.
plaPendingQueued to run. Only reported by legacy operating systems.
plaUndefinedUnable to determine status. Usually reported by Autologgers.

Running this code on my computer produces:

   plaStopped   plaRunning   plaCompiling   

The timing isn’t guaranteed, so your results may vary.

You can examine the run results using the RPM.

Working with Data Collectors

Figure 10. Examining Data Collector Sets: Data collector sets contain one or more data collectors. You can view individual data collectors through the RPM.

Data collectors are the building blocks of data collector sets. They’re components that extract performance, trace, and registry data. The template we used to create the data collector sets in the preceding example has two data collectors: NT Kernel, a trace data collector, and Performance Counter, a performance data collector.

Figure 10 shows how you can use the RPM to examine data collectors visually.

Use the IDataCollectorSet.DataCollectors property to enumerate data collectors.

   // Enumerate the data collectors   foreach (IDataCollector collector       in collectorSet.DataCollectors)   {       Console.WriteLine(;       Console.WriteLine(collector.DataCollectorType);       Console.WriteLine(collector.OutputLocation);       Console.WriteLine();   }   

To add new data collectors, right-click on a data collector set in the RPM and then click New –> Data Collector. The four types of data collectors shown in Figure 11 map to interfaces in the PLA API as shown in Table 3.

Figure 11. Creating a Data Collector: Use the RPM Data Collector Wizard to add and configure data collectors in data collector sets.

Table 3. Data Collector Types and Interfaces: The table shows how the data collector types map to interfaces in the PLA API.
Data CollectorPLA Interface
Performance counterIPerformanceCounterDataCollector
Event traceITraceDataCollector
Performance counter alertIAlertDataCollector

The PLA also provides the IApiTracingDataCollector interface to collect information about Win32 calls in Kernel32.dll, Advapi32.dll, Gdi32.dll, and User32.dll.

Creating Data Collectors
Adding data collectors using the RPM is the preferred method for creating collectors; however, you can also create them programmatically using the IDataCollectorSet.DataCollectors property:

   // Create a simple performance counter collector   IPerformanceCounterDataCollector performanceCollector =      (IPerformanceCounterDataCollector)      collectorSet.DataCollectors.CreateDataCollector(      DataCollectorType.plaPerformanceCounter); = @"Sample performance counter collector";   performanceCollector.PerformanceCounters =       new string[] { @"Process(*)\% Processor Time" };   performanceCollector.SampleInterval = 5;      // Configure additional properties...   // Add it to the data collector set   collectorSet.DataCollectors.Add(performanceCollector);      // Commit the set under a new name   collectorSet.Commit(      @"ServiceDevX with additonal collectors", null,       CommitMode.plaCreateOrModify);   

The IDataCollectorSet.DataCollectors property is an instance of the DataCollectorCollection class. It provides two methods for creating a data collector. The first, DataCollectorCollection.CreateDataCollector, accepts a DataCollectorType enumeration as a parameter. You can cast the returned IDataCollector instance to the appropriate interface as shown in the preceding code snippet.

The other method, DataCollectorCollection.CreateDataCollectorFromXml, accepts an XML string used to configure the data collector. You can extract the appropriate XML segment from an exported data collector set’s XML. For example, the DevX.Pla.Template.xml file used in this article contains this segment:

        0     Performance Counter     Performance Counter     0               0     0     0                         1     0     3     Process(*)*     PhysicalDisk(*)*     Processor(*)*     ProcessorPerformance(*)*     ...      
Figure 12. Scheduling Runs: You schedule data collector set runs using the Properties window. You don’t have to provide a schedule, so some data collector sets may not be scheduled.

Save this segment as a separate XML file to create a performance counter data collector with DataCollectorCollection.CreateDataCollectorFromXml.

The same programmatic and XML file approaches for configuring a performance counter data collector apply to the other types of data collectors; however, the specifics of configuring each type of data collector are outside the scope of this article. See the Best Practices section at the end of this article for more information.

Scheduling Data Collector Set Runs
Open the properties dialog for a data collector set in the RPM to create and modify scheduled runs (see Figure 12).

Programmatically, use the IDataCollectorSet.Schedules property to schedule runs.

   if (collectorSet.SchedulesEnabled)   {       // Create and configure a schedule       ISchedule schedule = collectorSet.Schedules.CreateSchedule();       DateTime now = DateTime.Now.AddHours(1);          schedule.StartDate = now;       schedule.EndDate = now.AddDays(7);       schedule.Days = WeekDays.plaEveryday;       schedule.StartTime = now;          // Add the schedule to the data collector set       collectorSet.Schedules.Add(schedule);          // Commit the set under a new name       collectorSet.Commit(           @"ServiceDevX with schedule", null,            CommitMode.plaCreateOrModify);   }   

After running the preceding code, if you export this data collector set’s XML file you’ll find an appropriate section for the schedule:

         5/3/2007      5/10/2007      1:27:10 PM      127      

Best Practices for Creating PLA-Enabled Applications
The PLA API can be intimidating to learn and tedious to program if you don’t have some extra help. Consider adopting these best practices when approaching PLA-enabled applications:

  • Become familiar with the Windows Vista Reliability and Performance Monitor. It’s a valuable development tool for PLA programmers.
  • Determine which data collectors you need for your application, and invest some time learning how to configure them properly. Most of the data collectors represent a deep topic area?it doesn’t make sense to try to learn them all at once.
  • The deepest topic is performance counters. You might find the article Extracting Performance Data from Your .NET Applications valuable.
  • Use the XML capabilities of the PLA API to keep data collector set configuration decoupled from your application code.

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist