Jump to content



Photo

Performance Counters in Windows - Measure Process, CPU, Network, Disk Usage


  • Please log in to reply
123 replies to this topic

#1 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 05 March 2009 - 01:50 AM

PDH Performance Counters
Measure Process, CPU, Network, Process, Disk (etc) Usage

Posted Image
(note that the above dialog appears differently on Vista+)

New ObjectBase interface!!
*x64 and Localization Issues have been resolved!*

*Download and License agreement are at the bottom of this post!


About The Project:
Performance Counters gather all kind of performance data about the PC and the Network using the standard PDH.DLL module (standard since Windows 2000).

Among the performance data you can collect and monitor are:
  • Processor Stats (including total usage)
  • Process (programs) Stats (including CPU usage)
  • Disk Stats (speed/access)
  • TCP, UDP, IP Connection Counts, Speed/Error Stats
  • Network Stats
  • ..and so on
Note that one example is a WIP. 'TaskManager' mockup UDF, I'm looking at you.

You can jump right in, download the two AutoIT files (below) and run one of the following to see what the PDH Performance Counters project can get you:
  • TestPDH_PerformanceCounters - this is where you should start! It allows you to visually experiment with most all of the Counters available on your PC and Network.
    NOTES:
    - Currently the 'Refresh' rate is set to 1/2 second - this can be changed by altering the Adlib() function frequency
    - New Counters that come into existence during monitoring will *not* be added to the list (this would be a function I've yet to add)
    - Counters that become invalid are simply given a prefix of '[Dead Counter Handle]:'

Posted Image

  • TestPDH_ProcessLoop - this basically repeatedly shows an extended Process-information list for all processes. NOTE: You must hit 'ESC' to exit the loop

Posted Image

  • TestPDH_TaskManager - this gathers and displays most everything you'd see in the Process and Performance sections of Task Manager.
    NOTES:
    - The screen does NOT update, and the UDF is a MESS. This is due to a number of reasons - the biggest one being laziness on my behalf. Plus I need to figure out how best to manage ListView changes.
    - TWO fields need Windows XP+ to display correctly (or a version of psapi.dll that supports 'GetPerformanceInfo'): Commit Charge (Peak) and System Cache

Posted Image

  • TestPDH_ProcessGetRelatives - this shows how the PDH Performance Counters can be used to get 'parent' and 'children' process information. There are more practical means of getting this info of course (a few you'll see in my 'Process Functions' module, but hey - its just yet another example of what can be done.
  • TestPDH_ObjectTests - this is more for reading/understanding the code than anything. It is there to show how the new 'ObjectBase' Interface works to make coding Performance Counters *much* easier.
  • Multipile extra 'TestPDH*' examples
At its most basic, interacting with Performance Counters is as such:
Spoiler


The brand new ObjectBase Interface removes some of the difficulty in interacting with Performance Counters, and works like this:
Spoiler


Examples of the new ObjectBase interface:
% CPU Usage of a Process
% CPU Usage of Multiple Instances of a Process (+monitoring and adjustment based on new/dead Instances)

Other Examples:
Waiting for Hard Disk activity to Idle for 'x' ms
% System CPU Usage (by Processor)
Network Usage (bytes sent/received)
Physical Disk Read/Write Speed


I've put a LOT of work into this project, and all I ask is that you follow my License Agreement when using the code (very easy, see below). Any feedback is welcome. I apologize for the unpolished GUI interfaces (especially the unfinished one), but I will get to that TaskManager GUI one day, hah. Enough chatter -now go on and experience the awesome power of Performance Counters :P

Download the ZIP Here

NOTE: Bundled in the ZIP (and included in the License agreement) are other UDF's I wrote that are necessary to run some of the 'Test' programs:
_WinAPI_GetSystemInfo.au3, _WinAPI_GetPerformanceInfo.au3, _WinTimeFunctions.au3, and the unnecessary, but provided for those who are interested in the _WinTimeFunctions 'filetime' usage, program: TestWinTimeFunctions.au3.

Ascend4nt's AutoIT Code License agreement:
While I provide this source code freely, if you do use the code in your projects, all I ask is that:
  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.
Enjoy!
Ascend4nt

UPDATES:
Spoiler

Edited by Ascend4nt, 18 October 2012 - 12:03 PM.

  • n1maS likes this





#2 UEZ

UEZ

    Never say never

  • MVPs
  • 3,600 posts

Posted 05 March 2009 - 08:46 AM

Can I use it also for remote systems?

UEZ

 
The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯


#3 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 05 March 2009 - 12:38 PM

You should be able to. I made sure in the Browse Counters function to not set the 'local computer only' flag. Give it a try, let me know.

*edit- err, you did mean networked pc's right?

Edited by ascendant, 05 March 2009 - 01:08 PM.


#4 Manko

Manko

    Polymath

  • Active Members
  • PipPipPipPip
  • 229 posts

Posted 05 March 2009 - 02:42 PM

That was really frickin cool, ascendant! :P

Great job on packaging too!

/Manko
Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

#5 UEZ

UEZ

    Never say never

  • MVPs
  • 3,600 posts

Posted 05 March 2009 - 03:02 PM

You should be able to. I made sure in the Browse Counters function to not set the 'local computer only' flag. Give it a try, let me know.

*edit- err, you did mean networked pc's right?


Yep. You can use WMI for getting the counter from remote systems, e.g. servers.

I'm planning to implement performance counters to my sic project but until now I was just planning... :P

UEZ

 
The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯


#6 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 05 March 2009 - 03:13 PM

That was really frickin cool, ascendant! :P

Great job on packaging too!

/Manko


Thanks! haha.. I thought it was pretty cool too once I added the function to interact with the 'Browse Counters' dialog. I was like wow - I never imagined so much information was available.

Hey - have you tried the Process - %Processor Time Counter? I've tested this and the results don't match Task Manager. I'm thinking this *might* have something to do with multi-core processors? I'd have to take another look at one of the sources I used to see if there's a better method of calculating that properly.

-A

#7 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 05 March 2009 - 04:07 PM

@ascendant

Tested on several servers and working just fine.

This is indead a small master piece :P

Regards

ptrex

#8 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 05 March 2009 - 11:20 PM

..
This is indead a small master piece :P


I consider that a very high compliment. Thanks :unsure:

btw, there's *other* Counters that my functions don't cover - namely ones dealing with log files. Also, I prevented the 'Browse Counters Dialog' from displaying Counters considered 'Costly' - but that can easily be changed by adjusting the flags in that function. I'd be curious what those Counters are, but I'm guessing they aren't something you'd normally want to mess with due to the resource requirements..

#9 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 07 March 2009 - 09:28 PM

Updated!! CPU % Usage now reports values correctly! Finally, a person can create a Task Manager with this and a few other modules (without even touching WMI!) :P w00t!

Added a few other things - including manual entry in the GUI, new functions, etc..
More comprehensive list of updates/changes is in 1st post

#10 Manko

Manko

    Polymath

  • Active Members
  • PipPipPipPip
  • 229 posts

Posted 07 March 2009 - 10:40 PM

Updated!! CPU % Usage now reports values correctly!

Great! What did you do to fix it? What was the problem?

/Manko
Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually...

#11 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 07 March 2009 - 10:47 PM

Great! What did you do to fix it? What was the problem?

/Manko


Well, 2 things - I didn't set the 'PDH_FMT_NOCAP100' flag initially when calling 'PdhGetFormattedCounterValue', and 2nd I needed to divide the results (for only CPU usage counters) by the # of system reported CPU's. (I have a quad-core CPU btw - so once I set the 'NOCAP' flag, I was getting 400% usage total counts, which of course needed to be divided by 4).

#12 picaxe

picaxe

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 475 posts

Posted 08 March 2009 - 05:45 AM

Thanks for sharing :P

#13 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 09 May 2010 - 10:14 PM

Okay, I decided to release the PDH Performance Counters project in its current Work-in-Progress state. There's a lot of stuff to this project, and I hope to document it in the future, but for now you sorta have to make do. The test examples might help understand this better, and any questions I can probably help with. Again, I remind you, this is a W-I-P version, so there's a lot of stuff that needs refining, updating, and possibly x64 modifications.

NOTE also: Bundled in the ZIP [see first post] (and included in the License agreement) are other UDF's I wrote that are necessary to run some of the 'Test' programs:
_WinAPI_GetSystemInfo.au3, _WinAPI_GetPerformanceInfo.au3, _WinTimeFunctions.au3, and the unnecessary, but provided for those who are interested in the _WinTimeFunctions 'filetime' usage, program: TestWinTimeFunctions.au3.

UPDATES:

  • 5/9/2010: Releasing W-I-P since I feel the need for this is out there, even if the project is not complete.
    Note that there are extra modules includes for the 'Test' programs (_WinAPI_GetPerformanceInfo.au3, _WinAPI_GetSystemInfo.au3, _WinTimeFunctions.au3, and the unnecessary TestWinTimeFunctions.au3)
  • 5/09-5/2010 Updates: Added extra _PDH extended info modules, more functions in general (lost track, sorry), new Test programs, etc.
    - Bottom edit box now displays appropriate 'GetCounterInfo' for selected Counter Handle in listview.
  • 4/1/09 Update: Wildcard Counters support.


#14 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 14 May 2010 - 08:45 AM

Okay, x64 compatibility issues have been resolved. However, there is a strange issue with the 'Browse Counters' dialog box, most likely not related to any structure/size issues. It's *possibly* an issue with the 64-bit version of PDH.DLL, but I cannot yet be certain of where the issue lies.

Here's the deal: selecting any single object in a Counter with multiple instances (Processes for example) returns 'success', but NO string is returned - and GetLastError reports success! HOWEVER, select '<All instances>', and it returns a string. Go figure!

I haven't tested this on Win7 x64 yet, and haven't updated my Vista x64 test O/S to the latest fixes, so I would appreciate any testing anyone can do!

Updates:
  • 5/14/2010: x64 Compatibility Fixes. However, 'Browse Counters' dialog box has issues selecting some Counters. This may be an issue with PDH.DLL or something else (?).

Edited by Ascend4nt, 14 May 2010 - 08:46 AM.


#15 Fire

Fire

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 362 posts

Posted 14 May 2010 - 08:54 AM

Hi

BTW seems _WinAPI_GetSystemInfo.au3 missing?

Just downloaded and it is missing.Or i`m doing somethink wrong?

Posted Image


Thanks in advance.

#16 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 14 May 2010 - 09:05 AM

BTW seems _WinAPI_GetSystemInfo.au3 missing?


D'oh!! Sorry about that - I included the wrong file in the ZIP (_WinAPI_GetSystemTimes, oops). It should be fixed now.

Note to self: Test these projects in a separate folder before uploading!!

#17 Fire

Fire

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 362 posts

Posted 14 May 2010 - 09:22 AM

Thanks so much Ascend4nt

Works like charm and Great Job !!!

#18 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 14 May 2010 - 09:15 PM

Update:
*x64 Issues have finally been resolved completely!*

Yay!! Stupid bugger of a problem to find.. turns out there's just one flag that shouldn't be set on the Browse Counters dialog box for Vista+ O/S's.

I removed the 'W-I-P' part of the project title since it is now completely usable on any O/S Win2000+ in any bit-mode.

However, though the core PDH functions are good, other parts of the project can be considered Works-in-Progress. For one, the examples need to be completed (as in, they should update/refresh information). I also should probably rework some of the code in the extended PDH modules.

Otherwise, its all good. Of course, I'll be doing additional modifications of the core PDH module in the future too (namely - removing a few wrapper functions, altering one or two functions, and probably providing more options for some functions). But until then, happy 'Performance Counting'!

Edited by Ascend4nt, 14 May 2010 - 09:16 PM.


#19 KaFu

KaFu

    Hey, it's just me, KhaFoo...

  • MVPs
  • 3,162 posts

Posted 15 May 2010 - 02:19 PM

Hi m8,

thanks for this (as always :) ) great UDF. I wanted to utilize it in one of my projects, but ran into this error

CPU count result:4 _PDH_GetNewQueryHandle Call succeeded, return:0,param1:0x0000000000000000,param2:0,handle:0x00000000044112F0 PdhAddCounterW error [path:'\Process(*)\ID Process'], return:C0000BB8 PdhAddCounterW error [path:'\Process(*)\Creating Process ID'], return:C0000BB8 PdhCloseQuery DLL call successful Time for _PDH_ProcessGetChildren():456.555864370802 ms All (3) Child processes found via PDH for PID#4120: [Original PID's retrieved from Run() :5624]


trying this code

#include <PDHPerfCounters\_PDH_ProcessGetRelatives.au3> $iPID = Run("control mmsys.cpl", "", @SW_HIDE) $iTimer = TimerInit() $aChildProcesses = _PDH_ProcessGetChildren() Local $iExt = @extended ConsoleWrite("Time for _PDH_ProcessGetChildren():" & TimerDiff($iTimer) & " ms" & @CRLF) If $iExt = 0 Then     ConsoleWrite("No Child Processes found for PID#" & @AutoItPID & @CRLF) Else     ProcessClose($iPID)     Local $sOutputStr = ""     For $i = 0 To UBound($aChildProcesses) - 1         $sOutputStr &= "Child Process found: Process ID#" & $aChildProcesses[$i][0] & ", name: '" & $aChildProcesses[$i][1] & "'" & @CRLF     Next     $sOutputStr &= @CRLF & "[Original PID's retrieved from Run(): " & $iPID & "]"     ConsoleWrite("All (" & $iExt & ") Child processes found via PDH for PID#" & @AutoItPID & ':' & @CRLF & $sOutputStr & @CRLF)     MsgBox(0, "(" & $iExt & ") Child Processes found via PDH for PID#" & @AutoItPID & ' (all closed):', $sOutputStr) EndIf


Win7 64bit Ultimate, maybe you'll find time to take a look :idea: ...

Edited by KaFu, 15 May 2010 - 02:21 PM.


#20 Ascend4nt

Ascend4nt

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,072 posts

Posted 15 May 2010 - 09:01 PM

Well darn, if only I installed Win7 x64 so I could test this there. So far, the code you posted executed fine for me on Vista x64 (both 32-bit and 64-bit modes) and Win7 x86, but I don't yet have an install of Win7 x64 to test. (need to make room for it argh)

Okay.. before I go crazy and clear out space and install the O/S, do me a favor and look in your registry at these keys:
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfOS\Performance"
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance"

See if they exist and this value exists (and what it is set to):
"Disable Performance Counters"

My 'Init' routine looks at those keys and *should* try to enable performance counters if that value exists, but it would probably give UAC prompts.

Also - a note on the code - the value you are getting in $iExt is an extended error code (probably the same as $_PDH_iLastError). I'm not sure what the context is - you'd have to add an @error check and output it.

However - the 'PdhAddCounterW' code in your output (C0000BB8) is defined as PDH_CSTATUS_NO_OBJECT, which MSDN defines as 'Unable to find the specified object on the computer or in the log file.'

Looking further, it looks like this *may* be a problem with non-English versions of Windows. (Perhaps you have a foreign language version installed?)

Per user comments on 'PdhAddCounterFunction' on MSDN, "The counter path specified in szFullCounterPath should be localized, or the function may fail on non-English versions of Windows."

If you'd be so kind, and if it is a non-English version of Windows you are using, could you try replacing 'PdhAddCounterW' in the DLLCall in the '_PDH_PerformanceCounters' module with 'PdhAddEnglishCounterW'? All the other parameters should remain the same. This function is a Vista+ function, so I might have to add a @OSVersion check before this call.

Sorry to put you to work, but hey - I'll be very grateful! Thanks in advance!

*edit: also, do me a favor and see what keys are under this key in your registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib

(I only have 009 (English))

Edited by Ascend4nt, 15 May 2010 - 10:43 PM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users