How To Retrieve Performance Counter Value Using PDH

Summary

Performance Data Helper (PDH) APIs can be used to collect performance data of various performance counters or instances that are available on the system. This article demonstrates the PDH API calls that are needed to collect performance data for a performance object, counter, and instance name.

More Information

The sample code below has a PDH_COUNTER_PATH_ELEMENTS CPE table that specifies the performance object, counter, and instance names for which the application is collecting the performance data.

#include <windows.h>
#include <pdh.h>
#include <stdio.h>

BOOL WINAPI GetCounterValues(LPTSTR serverName);

void main(int argc, char *argv[])
{
if (argc > 1)
{
// argv[1] - Server Name

GetCounterValues(argv[1]);
}
else
{
// Local System

GetCounterValues(NULL);
}
}

BOOL WINAPI GetCounterValues(LPTSTR serverName)
{
PDH_STATUS s;

HQUERY hQuery;

// Array to specify the performance object, counter and instance for
// which performance data should be collected.

// typedef struct _PDH_COUNTER_PATH_ELEMENTS {
// LPTSTR szMachineName;
// LPTSTR szObjectName;
// LPTSTR szInstanceName;
// LPTSTR szParentInstance;
// DWORD dwInstanceIndex;
// LPTSTR szCounterName;
// } PDH_COUNTER_PATH_ELEMENTS, *PPDH_COUNTER_PATH_ELEMENTS;

// Each element in the array is a PDH_COUNTER_PATH_ELEMENTS structure.
PDH_COUNTER_PATH_ELEMENTS cpe[] =
{
{ NULL, "Memory", NULL, NULL, -1, "Cache Bytes" },
{ NULL, "Memory", NULL, NULL, -1, "Available Bytes" },
{ NULL, "Processor", "_Total", NULL, -1, "% Processor Time" }
};

HCOUNTER hCounter[sizeof(cpe)/sizeof(cpe[0])];

char szFullPath[MAX_PATH];
DWORD cbPathSize;
int i, j;

BOOL ret = FALSE;

PDH_FMT_COUNTERVALUE counterValue;

// Only do this setup once.
if ((s = PdhOpenQuery(NULL, 0, &hQuery)) != ERROR_SUCCESS)
{
fprintf(stderr, "POQ failed %08x\n", s);
return ret;
}

for (i = 0; i < sizeof(hCounter)/sizeof(hCounter[0]); i++)
{
cbPathSize = sizeof(szFullPath);

cpe[i].szMachineName = serverName;

if ((s = PdhMakeCounterPath(&cpe[i],
szFullPath, &cbPathSize, 0)) != ERROR_SUCCESS)
{
fprintf(stderr,"MCP failed %08x\n", s);
return ret;
}

if (cpe[i].szInstanceName)
{
printf("Adding [%s\\%s\\%s]\n",
cpe[i].szObjectName,
cpe[i].szCounterName,
cpe[i].szInstanceName);
}
else
printf("Adding [%s\\%s]\n",
cpe[i].szObjectName,
cpe[i].szCounterName);

if ((s = PdhAddCounter(hQuery, szFullPath, 0, &hCounter[i]))
!= ERROR_SUCCESS)
{
fprintf(stderr, "PAC failed %08x\n", s);
return ret;
}
}

for (i = 0; i < 20; i++)
{
Sleep(100);

// Collect data as often as you need to.
if ((s = PdhCollectQueryData(hQuery)) != ERROR_SUCCESS)
{
fprintf(stderr, "PCQD failed %08x\n", s);
return ret;
}

if (i == 0) continue;

// Extract the calculated performance counter value for each counter or
// instance.
for (j = 0; j < sizeof(hCounter)/sizeof(hCounter[0]); j++)
{
if ((s = PdhGetFormattedCounterValue(hCounter[j], PDH_FMT_DOUBLE,
NULL, &counterValue)) != ERROR_SUCCESS)
{
fprintf(stderr, "PGFCV failed %08x\n", s);
continue;
}
if (cpe[j].szInstanceName)
{
printf("%s\\%s\\%s\t\t : [%3.3f]\n",
cpe[j].szObjectName,
cpe[j].szCounterName,
cpe[j].szInstanceName,
counterValue.doubleValue);
}
else
printf("%s\\%s\t\t : [%3.3f]\n",
cpe[j].szObjectName,
cpe[j].szCounterName,
counterValue.doubleValue);
}
}

// Remove all the counters from the query.
for (i = 0; i < sizeof(hCounter)/sizeof(hCounter[0]); i++)
{
PdhRemoveCounter(hCounter[i]);
}

// Only do this cleanup once.
PdhCloseQuery(hQuery);

return TRUE;
}

References

PDH APIs are implemented in the Pdh.dll file that ships with the Microsoft Windows 2000 and Microsoft Windows XP operating system. For the Microsoft Windows NT 4.0 operating system, you can download a separate redistributable Pdh.dll version.


For additional information on how to obtain the redistributable version of Pdh.dll for Windows NT 4.0, click the article number below to view the article in the Microsoft Knowledge Base:

284996 FILE: Latest Redistributable PDH.dll Available for Windows NT 4.0
For additional information on the PDH APIs, see the "Performance Monitoring" topic in the "Base Services" section of the MSDN Library.
Propriedades

ID do Artigo: 287158 - Última Revisão: 21 de nov de 2006 - Revisão: 1

Comentários