Jump to content
Sign in to follow this  
targeter

monitor cpu usage using WinAPI like Task Manager

Recommended Posts

targeter

I know there are a couple of ways to do this. And some people on the forums have written scripts. However, most are process specific monitoring.

I was interesting in polling the cpu usage data for a specific moment in time. So that I could log CPU load on a server over time. Similar to this. http://sourceforge.net/projects/cpu-usage-log/

Of the many ways to do this, I want the information to reflect what the user would see if they opened Windows Task Manager. If you analyze the import tables of WTM, you see the program is using NtQuerySystemInformation.

So my idea is to get generate the information in the same way, since there is no specific API call for CPU usage. This would kind of be a micro task manager for Autoit.

This requires the use of the http://msdn.microsoft.com/en-us/library/ms724400 GetSystemTime DLLCall to retreive the following:

IdleTime

KernelTime

UserTime

System time = kernelttime + usertime

So CPU Usage can be calulated as such.

cpu load = int( (SystemTime - IdleTime) *100 / Systemtime );

I am a little confused by the DLLCall itself though. It seems like I might have to treat each one of the three as a separate array because of low and high times.

Even if that is resolved, I think this would inaccurate on machines that use multiple cores, right? How would that factor in?

Edited by targeter

Share this post


Link to post
Share on other sites
Ascend4nt

I just added an example to my 'Performance Counters in Windows - Measure, Analyze, Collect Performance Info' UDF, the post link is here -> Example #4: % System CPU Usage (by Processor).

The UDF uses API calls to get the info and works quick enough ;)

Edited by Ascend4nt

Share this post


Link to post
Share on other sites
targeter

I just added an example to my 'Performance Counters in Windows - Measure, Analyze, Collect Performance Info' UDF, the post link is here -> Example #4: % System CPU Usage (by Processor).

The UDF uses API calls to get the info and works quick enough ;)

Wow... it is pretty close to what WTM is parsing out. I there are minor discrepancies. I wonder if this has to do with you using pdh instead of the kernel32.dll that I was kind of trying to go after. The resolution on the usage seems to be very similar within 5% depending on scenario though.....

I wonder if pdh is using information pulled from the kernel. Because I am pretty sure this is what CPUID/HWMonitor is using.....

Share this post


Link to post
Share on other sites
seandisanti

Wow... it is pretty close to what WTM is parsing out. I there are minor discrepancies. I wonder if this has to do with you using pdh instead of the kernel32.dll that I was kind of trying to go after. The resolution on the usage seems to be very similar within 5% depending on scenario though.....

I wonder if pdh is using information pulled from the kernel. Because I am pretty sure this is what CPUID/HWMonitor is using.....

you're going to have discrepancies also based on the time allotted to the program you're using to check perfomance....

Share this post


Link to post
Share on other sites
Ascend4nt

Wow... it is pretty close to what WTM is parsing out. I there are minor discrepancies. I wonder if this has to do with you using pdh instead of the kernel32.dll that I was kind of trying to go after. The resolution on the usage seems to be very similar within 5% depending on scenario though.....

I wonder if pdh is using information pulled from the kernel. Because I am pretty sure this is what CPUID/HWMonitor is using.....

There's no way to perfectly sync Task Manager with the example I gave you, as its hard to determine what rate Task Manager is updating CPU usage (my example was polling ever 1/4 second). That's one reason you'll see more variations - the timing and update frequency. If however you have a constant amount of CPU load (run SP2004 on one CPU for example), you'll see they sync up - usually within 1%. The discrepancy is possibly due to the fact I don't grab the percentage as a float, but instead as an integer..

As far as PDH.DLL it is just an API interface to the registry Performance Counters <- MSDN link. I couldn't tell you for certain what Task Manager uses, but my guess is it accesses them through the registry interface, rather than through per-process and per-CPU calculations.

*edit: link jumped to comments

Edited by Ascend4nt

Share this post


Link to post
Share on other sites
targeter

There's no way to perfectly sync Task Manager with the example I gave you, as its hard to determine what rate Task Manager is updating CPU usage (my example was polling ever 1/4 second). That's one reason you'll see more variations - the timing and update frequency. If however you have a constant amount of CPU load (run SP2004 on one CPU for example), you'll see they sync up - usually within 1%. The discrepancy is possibly due to the fact I don't grab the percentage as a float, but instead as an integer..

As far as PDH.DLL it is just an API interface to the registry Performance Counters <- MSDN link. I couldn't tell you for certain what Task Manager uses, but my guess is it accesses them through the registry interface, rather than through per-process and per-CPU calculations.

*edit: link jumped to comments

I looked at WTM. If you analyze the import tables of WTM, you see the program is using NtQuerySystemInformation. at kernel32.dll.

Share this post


Link to post
Share on other sites
Ascend4nt

I looked at WTM. If you analyze the import tables of WTM, you see the program is using NtQuerySystemInformation. at kernel32.dll.

If you look a little deeper at the Imports information in WTM, you'll also see that RegQueryValueEx is listed, which is the primary interface many programs use for accessing performance counters (HKEY_PERFORMANCE_DATA). What I guess I'm saying here is, just because you see something in an Import table doesn't really mean you've figured out how a program works.

However, since I'm a bit familiar with NtQuerySystemInformation, and the various information you can get from it, I'd say yes it is possible to get the values that route by calculating the percentages yourself using the Idle/Kernel/User times you get. The Information Class you'd be looking for is 8, which will get you an array of SYSTEM_PROCESSOR_TIMES (1 for each processor [possibly a logical CPU count here, but I'm not certain]), from which you can do your calculations. Whether WTM uses this method, neither of us will know unless we had the source code. I will tell you however that NtQuerySystemInformation has many other functions that Task Manager can make use of for getting information on the System Cache, page file, handles, and many other resources in use. WTM doesn't have any obvious Imports for calculating Process % CPU usage, so who knows, it may use Performance data queries for that.

Whatever the case, I did my part and produced a little example piece of code that shows exactly what the system is reporting in terms of performance data, so really I don't see how it's a problem. When the PDH query and counters are all set up, a call to_PDH_CollectQueryData takes a snapshot of the performance data and stores that snapshot until the next one is taken. The successive calls to _PDH_UpdateCounter simply pull out values from each individual snapshot.

If it's not what you want, that's fine. I'd be interested in seeing what you come up with.

Share this post


Link to post
Share on other sites
targeter

Actually that explanation makes more sense. I was in seattle and had talked to a ms mvp who I asked answered my question....

I meant no offense. Actually your code is still better than what I could produce even if I had an extended project timeline. ;)

I suppose the bottomline really is the actual numbers. Now that I've been thinking about it... the WTM's high refresh (250 milliseconds?) normal (1 second), and low (4 seconds) might actually factor in millisecond time. SYSTEMTIME has a millisecond resolution, so even if I was to sync it up to the second, I have no idea what second it is actually occurring at... There seems to be little chance to do an exact sync.

I took at stab at kind of replacing your DLLcall with my idea and trying to sync it up with WTM.... no diff with yours. I think the millisecond thing is kind of screwing up any chance of sync (using date udf to check intervals). I wonder if when wtm does its normal refresh mode if it does it with milliseconds according to the start time of the monitoring, i.e. XX:XX:01.234 then XX:XX:02.234....

I've probably spend more time thinking about this than I had originally planned... :)

Edited by targeter

Share this post


Link to post
Share on other sites
Ascend4nt

Why is it important to sync up with the frequency that Task Manager displays at? If you're getting accurate (or very-near-accurate) results of what the % is, why bother looking at Task Manager at all?

The best part of PDH counters? You can monitor ANY PC on a network (assuming you have the rights to access those PC's) and see what is happening with each one - including things like what processes are running, network, disk & CPU usage and so on (all of what's available through Performance Counters really).

Share this post


Link to post
Share on other sites
DanRiek

I am really new to Autoit so please forgive me. I want to get Process info from another machine(process, % CPU, etc) on a network. Can the TestPDH_TaskManager.au3 be run on one machine to get the information off of another?

Thanks

Share this post


Link to post
Share on other sites
Ascend4nt

Yes, but you need the rights to read them, and their computers must have Remote registry or whatnot turned on. You just need to enter the computer name (like "\\ComputerA") and it should connect and retrieve that info. You might have to log into that computer as an administrator.. this part I'm not entirely sure of, so test it out and let me know. It's worked for me when I've tested it from a Win XP machine to Win2000..

*edit: by log in, I mean remotely log in

Edited by Ascend4nt

Share this post


Link to post
Share on other sites
targeter

It worked for me. Ascend4nt has an excellent script. If you want monitoring, this is probably the best solution on the autoit side.

Share this post


Link to post
Share on other sites
DanRiek

I am not sure where to add the "\\Computer Name". What procedure does this get added to?

Thanks

Share this post


Link to post
Share on other sites
Ascend4nt

Using the Test program, look at the Browse Counters dialog. You'll see a "Select counters from computer" option. In that edit box, enter the PC name. You might need to hit 'Tab' or something once this is done for the other fields to refresh.

Share this post


Link to post
Share on other sites
DanRiek

Thanks I did not see this one: TestPDH_PerformanceCounters.au3.

I have looked at TestPDH_TaskManager.au3 and it seems easier for me to understand. I have modified this one to just print to a file Process and CPU% but it only does this for the local machine. It seems to work very well and is perfect for for what I need but it looks like this procedure only will run on the local machine. I am wondering if there is a way to modify this to get information from a remove machine. Thanks

Share this post


Link to post
Share on other sites
Ascend4nt

From my _PDH_PerformanceCounterNotes.txt file (recent update, not uploaded yet):

; ===============================================================================================================================
; Performance Counters Requirements:
; ===============================================================================================================================
; Machine must support PDH (Win2000+), and not have any of the following registry values set to 1:
;
; - Key: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib
;   - Value: Disable Performance Counters (REG_DWORD, 1 = Disabled, 0 = Enabled)
;
; - Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfOS\Performance
;   - Value: Disable Performance Counters (REG_DWORD, 1 = Disabled, 0 = Enabled)
;
; - Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance
;   - Value: Disable Performance Counters (REG_DWORD, 1 = Disabled, 0 = Enabled)
;
; Remote machines can be accessed, but the current machine must have the proper permissions and/or be logged in.
; Additionally, the Remote machine must:
; - be turned on and connected to the network [LAN enabled]
; - have permissions set on the registry that allows remote connections and/or remote performance monitoring by the user.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×