Platform SDK: Performance Monitoring

Displaying Performance Data

The raw value of many counters may not be useful for you—you might need to format the values for display. To get the information in the form described by most counter names, you need to compute the displayable value based on this raw data. Pdh functions can do this for you. For example, the Page Faults/Sec counter simply counts page faults, so if you view the raw data, you see a running total of page faults. To get the rate implied by the counter name, page faults per second, you need to call the PdhGetFormattedCounterValue function. In this case, the function divides the difference between two samples by the time between the samples. The PdhGetFormattedCounterValue function performs its computations on the sample returned by the last call to PdhCollectQueryData.

You can retrieve raw counter data with the PdhGetRawCounterValue function. If the raw data will be formatted later, store the raw data, and call the PdhFormatFromRawValue function to perform the calculation on the stored data. For time-based counter values, call PdhGetCounterTimeBase before PdhFormatFromRawValue to get the counter's time base.

Note  The PdhCalculateCounterFromRawValue function incorporates the functionality of PdhGetCounterTimeBase and PdhFormatFromRawValue into one function.

PdhGetFormattedCounterValue and PdhGetRawCounterValue are used to get single counter values. In situations where you may want to retrieve more than one counter value, the PdhGetFormattedCounterArray and PdhGetRawCounterArray functions are provided. PdhGetFormattedCounterArray and PdhGetRawCounterArray accept only counter handle (hCounter) values that have been created with PdhAddCounter where the wildcard characters in the counter name string were specified for instance names, not performance object or counter names. For example, a counter handle created with the counter name string "\Explorer(*)\ID Process" is valid for use with PdhGetFormattedCounterArray and PdhGetRawCounterArray. A counter handle created with the counter name string "\Processor\* Bypasses/sec" is not.

In both of these functions, the counter values are returned in a buffered set of PDH_RAW_COUNTER_ITEM structures in the case of PdhGetRawCounterArray and PDH_FMT_COUNTERVALUE_ITEM structures in the case of PdhGetFormattedCounterArray.

Note that there are no links between the structures; therefore, the read pointer must be moved forward the number of bytes corresponding to the size of a structure to get the next counter value in the array. When you have retrieved an array of raw counter values, the PdhComputeCounterStatistics function will take the buffered counter values and compute the minimum, maximum, and mean values. It returns the statistical values in a PDH_STATISTICS structure. An example of when this would be done is in compressing a log file. To compress a log file, call PdhComputeCounterStatistics to compute the mean of a number of raw counter values and then write the mean to an output log file as a log file record.

Remember to check the CStatus member of the PDH_RAW_COUNTER structure (contained in the PDH_RAW_COUNTER_ITEM structure you pass into PdhComputeCounterStatistics) for a value of PDH_CSTATUS_NEW_DATA or PDH_CSTATUS_VALID_DATA before reading the values from the structure. If the value of CStatus is anything other than PDH_CSTATUS_NEW_DATA or PDH_CSTATUS_VALID_DATA, the counter values are not valid.