Perl – CPU and RAM Utilization of an application via WMI
In Perl, we can query the Windows Operating system using winmgmt service (A WMI Service) to get the CPU and RAM utilization of an application or process.
We can get the instance of winmgmt object in Perl using Win32::OLE library and run our select query to fetch the CPU and RAM utilization for a process using its Process ID or Process Name.
Using winmgmt we can perform almost all operations in a windows machine such as starting and stopping a windows service, getting the Operating System details, statists, network activity, storage management, etc…
Connecting to a WMI Service:
We can connect to a WMI Object in two ways
- Retrieve an instance of an object using the GetObject function with a moniker string in the input parameter or
- Create a SWbemLocator object, and then use the ConnectServer method to log on to a namespace.
A moniker is a standard COM mechanism for encapsulating the location and binding of another COM object. To connect to a WMI object using a moniker, pass the name of the WMI Scripting Library's moniker, which is "winmgmts:" followed by the name of the target computer as the parameter to the Perl GetObject function.
In the below example we have used //./ to indicated that we are connecting to the local computer. To connect to a remote computer replace the period(.) in //./ with remote computer name.
Win32::OLE->GetObject("winmgmts://./root/cimv2")
More details on writing a moniker string and connecting through SWbemLocator is provided at https://technet.microsoft.com/en-us/library/bb684728.aspx
Steps to get CPU and RAM Utilization Data in Perl
-
-
- Include Win32 OLE library in Perl Scripting using the syntax
use Win32::OLE('in');
- Get the instance of winmgmt object using
Win32::OLE->GetObject("winmgmts://./root/cimv2");
- Get the total number of logical processor in a System using the below winmgmt select query. We will need the logical processor count to calculate CPU Utilization data.
select NumberOfLogicalProcessors from Win32_ComputerSystem
- Get the CPU and RAM utilization data using the query
select * from Win32_PerfRawData_PerfProc_Process where IDProcess=1234
The number 1234 has to be replaced with correct PID during execution.
The Operating System has to be queried minimum of two times to get the correct CPU utilization data. A minimum delay of 25ms is needed between each query for CPU% Utilization calculation.
In the query we can use various SQL clauses like WHERE, OR, AND, etc... The complete list of available clauses is provided in the link https://msdn.microsoft.com/en-us/library/aa394606(v=vs.85).aspx
- Apply CPU utilization calculation formula (explained below) to get the correct Utilization data
- Print the result or process the CPU and RAM utilization data as required
- Include Win32 OLE library in Perl Scripting using the syntax
-
Code - CPU and RAM Utilization data using Perl
###################################### ##### www.craftedforeveryone.com ##### ###################################### #### OS : Windows 10 64 Bit ########## #### Perl : v5.26.1 Strawberry Perl ## ###################################### use strict; use warnings; use Win32::OLE('in'); my $processorCount; my $statsQuery; #Get the WinMgmts Object Instance my $objWMIService = Win32::OLE->GetObject("winmgmts://./root/cimv2") or die "WMI connection failed.n"; sub main() { $statsQuery="select * from Win32_PerfRawData_PerfProc_Process where IDProcess=".$$; #Use this query to retrieve utilization data based on Process ID #$statsQuery="select * from Win32_PerfRawData_PerfProc_Process where Name='Taskmgr'"; #Use this query to retrieve utilization data based on Process Name. Process name should be be name displayed in Task Manager Details tab. ".exe" should be omitted GetProcessorCount(); GetUtilizationStats(); } sub GetProcessorCount() { my $cols=$objWMIService->ExecQuery("select NumberOfLogicalProcessors from Win32_ComputerSystem"); foreach my $v (in $cols) { $processorCount = $v->{NumberOfLogicalProcessors}; } } sub GetUtilizationStats() { my $processingTime=0; my $timeStamp=0; my $cpu=0; my $ram=0; my $name; while(sleep 1) { my $cols = $objWMIService->ExecQuery($statsQuery); foreach my $Data( in $cols){ $name=$Data->{Name}; $cpu = GetCorrectCPUData($processingTime,$Data->{PercentProcessorTime},$timeStamp,$Data->{TimeStamp_Sys100NS}); $processingTime=$Data->{PercentProcessorTime}; $timeStamp=$Data->{TimeStamp_Sys100NS}; $ram=$Data->{WorkingSetPrivate}; } print "Name :".$name.", CPU:".sprintf("%.2f",$cpu)."%, RAM:".$ram."n"; } } sub GetCorrectCPUData() { #CPU utilization calculation logic. my $oldProcessingData = shift; my $newProcessingData = shift; my $oldProcessingTime = shift; my $newProcessingTime = shift; my $diffProcessingData = ($newProcessingData - $oldProcessingData); my $diffProcessingTime = ($newProcessingTime - $oldProcessingTime); my $utilization=(($diffProcessingData/$diffProcessingTime)*100)/$processorCount; return $utilization; } main();
Program Execution Output:
The Perl script shown above will run in an infinite loop with a sleep time of 1 second to retrieve the CPU and RAM Utilization data.
The CPU utilization is calculated based on the values retrieved PercentProcessorTime and TimeStamp_Sys100NS, whereas RAM utilization is retrieved from WorkingSetPrivate
Using Win32_PerfRawData_PerfProc_Process class, we can retrieve the values for PercentProcessorTime and TimeStamp_Sys100NS. The complete list of parameters that are available for us to use from Win32_PerfRawData_PerfProc_Process class is provided in the link https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx
The Win32_ComputerSystem class also provides us a set of interesting parameters for us to use in a script. The full list of available parameters can be found in https://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx
CPU% Utilization Formula:
p1 refers to the PercentProcessorTime value retrieved while executing the Win32_PerfRawData_PerfProc_Process query for the first time, and p2 refers to the data retrieved while querying for the second time. Whereas t1 and t2 refers to TimeStamp_Sys100NS values.
1 Response
[…] A sample Perl code for this can be found in the link http://www.craftedforeveryone.com/cpu-and-ram-utilization-of-an-application-using-perl-via-wmi/ […]