直接上代码:
#include <windows.h>
#include <stdio.h>
#include <pdh.h>
#include <pdhmsg.h>
#pragma comment(lib, "pdh.lib")
BOOL DiskIOMon()
{
//CONST PWSTR COUNTER_PATH = L"\\Processor(0)\\% Processor Time";
//CONST PWSTR COUNTER_PATH = L"\\Processor(_Total)\\% Processor Time";
//CONST PWSTR COUNTER_PATH = L"\\Process(*)\\% Processor Time";
//CONST PWSTR COUNTER_PATH = L"\\Process(QQ)\\% Processor Time";
CONST PWSTR COUNTER_PATH = L"\\PhysicalDisk(_Total)\\% Disk Time";
//CONST PWSTR COUNTER_PATH = L"\\PhysicalDisk(_Total)\\Current Disk Queue Length";
//CONST PWSTR COUNTER_PATH = L"\\LogicalDisk(_Total)\\% Free Space";
HQUERY hQuery = NULL;
HCOUNTER hCounter = NULL;
PDH_STATUS status = ERROR_SUCCESS;
DWORD dwFormat = PDH_FMT_DOUBLE;
PDH_FMT_COUNTERVALUE ItemBuffer;
// Opens the log file that Writein Performance Data to a Log File
// example created.
status = PdhOpenQuery(0, 0, &hQuery);
if (ERROR_SUCCESS != status)
{
wprintf(L"PdhOpenQuery failed with 0x%x\n", status);
goto cleanup;
}
// Add the same counter used when writing the log file.
status = PdhAddCounter(hQuery, COUNTER_PATH, 0, &hCounter);
if (ERROR_SUCCESS != status)
{
if(PDH_CSTATUS_NO_OBJECT == status) //0xC0000BB8
{
wprintf(L"The specified object is not found on the system.\n");
}
else
wprintf(L"PdhAddCounter failed with 0x%x\n", status);
goto cleanup;
}
// Read a performance data record.
status = PdhCollectQueryData(hQuery);
if (ERROR_SUCCESS != status)
{
wprintf(L"PdhCollectQueryData failed with 0x%x\n", status);
goto cleanup;
}
while (ERROR_SUCCESS == status)
{
// Read the next record
status = PdhCollectQueryData(hQuery);
Sleep(100);
if (ERROR_SUCCESS == status)
{
// Format the performance data record.
status = PdhGetFormattedCounterValue(hCounter,
dwFormat,
(LPDWORD)NULL,
&ItemBuffer);
if (ERROR_SUCCESS != status)
{
wprintf(L"PdhGetFormattedCounterValue failed with 0x%x.\n", status);
goto cleanup;
}
wprintf(L"Formatted counter value = %.20g\n", ItemBuffer.doubleValue);
}
else
{
if (PDH_NO_MORE_DATA != status)
{
wprintf(L"PdhCollectQueryData failed with 0x%x\n", status);
}
}
}
cleanup:
// Close the query.
if (hQuery)
PdhCloseQuery(hQuery);
return TRUE;
}
需要注意的地方是收集数据需要时间,要增加Sleep延迟,否则收集到的值都是0或者1.
===================================================================================================
如果打不开定时器,返回错误 0xC0000BB8
msdn上对此错误的解释为
0xC0000BB8 PDH_CSTATUS_NO_OBJECT
The specified object is not found on the system.
原来是系统怕性能计数器影响系统的性能,而关闭了相关的计数器对象。
那么我们通过注册表去打开好了。
路径如下:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Performance
Disable Performance Counters :0x000
把上面的那个项修改为0x000就行了。
//IsOpen,打开传入为TRUE,关闭传递FALSE
void AssertNotDiableTheRasObject(BOOL IsOpen)
{
//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Performance
HKEY hKey;
long ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Performance"),0,KEY_ALL_ACCESS,&hKey);
if(ret0 == ERROR_SUCCESS)
{
DWORD dwDiable;
DWORD cbData_1 = sizeof(DWORD);
RegQueryValueEx(hKey, _T("Disable Performance Counters"), NULL, NULL, (LPBYTE)&dwDiable, &cbData_1);
if (dwDiable== IsOpen)
{
dwDiable= !IsOpen;
RegSetValueEx(hKey, _T("Disable Performance Counters"), NULL,REG_DWORD, (LPBYTE)&dwDiable, cbData_1);
}
RegCloseKey(hKey);
}
}
================================================================================================
附带微软的性能计数器:http://technet.microsoft.com/en-us/library/cc938959.aspx
磁盘的计数器
Counter | Description |
---|---|
LogicalDisk\% Free Space | Reports the percentage of unallocated disk space to the total usable space on the logical volume. When calculating the _Total instance, the %Free Space counters recalculate the sum as a percentage for each disk. |
LogicalDisk|PhysicalDisk\Avg. Disk Bytes/Transfer | Measures the size of input/output (I/O) operations. The disk is efficient if it transfers large amounts of data relatively quickly. |
LogicalDisk|PhysicalDisk\Avg. Disk sec/Transfer | Indicates how fast data is being moved (in seconds). Measures the average time of each data transfer, regardless of the number of bytes read or written. Shows the total time of the read or write, from the moment it leaves the Diskperf.sys driver to the moment it is complete. |
LogicalDisk|PhysicalDisk\Avg. Disk Queue Length | Tracks the number of requests that are queued and waiting for a disk during the sample interval, as well as requests in service. As a result, this might overstate activity. |
LogicalDisk|PhysicalDisk\Current Disk Queue Length | Indicates the number of disk requests that are currently waiting as well as requests currently being serviced. Subject to wide variations unless the workload has achieved a steady state and you have collected a sufficient number of samples to establish a pattern. |
LogicalDisk|PhysicalDisk\Disk Bytes/sec | Indicates the rate at which bytes are transferred and is the primary measure of disk throughput. |
LogicalDisk|PhysicalDisk\Disk Transfers/sec | Indicates the number of read and writes completed per second, regardless of how much data they involve. Measures disk utilization. |
LogicalDisk\Free Megabytes | Reports the amount of bytes on the disk that are not allocated. |
LogicalDisk|PhysicalDisk\Split IO/sec | Reports the rate at which the operating system divides I/O requests to the disk into multiple requests. A split I/O request might occur if the program requests data in a size that is too large to fit into a single request or if the disk is fragmented. Factors that influence the size of an I/O request can include application design, the file system, or drivers. A high rate of split I/O might not, in itself, represent a problem. However, on single-disk systems, a high rate for this counter tends to indicate disk fragmentation. |
LogicalDisk|PhysicalDisk\% Disk Time | Reports the percentage of time that the selected disk drive is busy servicing read or write requests. Because this counters data can span more than one sample, and consequently overstate disk utilization, compare this value against % Idle Time for a more accurate picture. |
LogicalDisk|PhysicalDisk\% Disk Write Time | Reports the percentage of time that the selected disk drive is busy servicing write requests. |
LogicalDisk|PhysicalDisk\% Disk Read Time | Reports the percentage of time that the selected disk drive is busy servicing read requests. |
LogicalDisk|PhysicalDisk\% Idle Time | Reports the percentage of time that the disk system was not processing requests and no work was queued. Notice that this counter, when added to % Disk Time, might not equal 100 percent, because % Disk Time can exaggerate disk utilization. |
内存监视
To determine a baseline for your system, use the following counters to create logs of memory usage over an extended period (from several weeks to a month).
-
\Memory\Pages/sec
-
\Memory\Available Bytes
-
\Paging File(_Total)\% Usage
CPU
To determine the baseline, use the following counters to create logs of processor usage over an extended period (from several weeks to a month).
-
Processor\ % Processor Time
-
System\Processor Queue Length