mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 00:45:19 +00:00
Adding windows profiling tool and documentation on how to use it (#12090)
This relates to #11939 This PR adds the test tool and procedure used to profile orbit and osqueryd processes on Windows
This commit is contained in:
parent
a46f926391
commit
4428d1e1aa
102
orbit/tools/windows/process_profile_tool.ps1
Normal file
102
orbit/tools/windows/process_profile_tool.ps1
Normal file
@ -0,0 +1,102 @@
|
||||
#Requires -Version 5.0
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$TargetPID,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[int]$SampleIntervalInSecs = 10 #default to 10 secs
|
||||
)
|
||||
|
||||
Write-Host "PID to profile is $TargetPID."
|
||||
|
||||
# Path for the CSV and chart file
|
||||
$currentDirectory = Get-Location
|
||||
$csvFilePath = $currentDirectory.Path + "\process_profile_$TargetPID.csv"
|
||||
$chartFilePathCPU = $currentDirectory.Path + "\process_profile_cpu_$TargetPID.png"
|
||||
$chartFilePathMemory = $currentDirectory.Path + "\process_profile_memory_$TargetPID.png"
|
||||
|
||||
# Initialize an empty array for storing data
|
||||
$data = @()
|
||||
|
||||
# Load the required .NET assembly for charting
|
||||
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
|
||||
|
||||
# Create two charts and define CPU and Memory series
|
||||
$chartCPU = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
|
||||
$chartCPU.Width = 600
|
||||
$chartCPU.Height = 400
|
||||
|
||||
$chartMemory = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
|
||||
$chartMemory.Width = 600
|
||||
$chartMemory.Height = 400
|
||||
|
||||
$chartAreaCPU = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
|
||||
$chartAreaMemory = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
|
||||
|
||||
$chartAreaCPU.AxisY.Title = "CPU Percentage"
|
||||
$chartAreaCPU.AxisX.Title = "Time in Seconds"
|
||||
$chartAreaMemory.AxisY.Title = "Memory Megabytes"
|
||||
$chartAreaMemory.AxisX.Title = "Time in Seconds"
|
||||
|
||||
$chartAreaCPU.AxisX.Minimum = 0
|
||||
$chartAreaMemory.AxisX.Minimum = 0
|
||||
|
||||
$chartCPU.ChartAreas.Add($chartAreaCPU)
|
||||
$chartMemory.ChartAreas.Add($chartAreaMemory)
|
||||
|
||||
$cpuSeries = New-Object System.Windows.Forms.DataVisualization.Charting.Series
|
||||
$cpuSeries.Name = 'CPU'
|
||||
$cpuSeries.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
|
||||
|
||||
$memSeries = New-Object System.Windows.Forms.DataVisualization.Charting.Series
|
||||
$memSeries.Name = 'Memory'
|
||||
$memSeries.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
|
||||
|
||||
$chartCPU.Series.Add($cpuSeries)
|
||||
$chartMemory.Series.Add($memSeries)
|
||||
|
||||
# Initialize time
|
||||
$startTime = Get-Date
|
||||
$cpuCores = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors
|
||||
|
||||
Write-Host "Press any key to stop the data collection and generate profile charts."
|
||||
while($true) {
|
||||
if([System.Console]::KeyAvailable) {
|
||||
Write-Host "Key Pressed. Stopping script..."
|
||||
break
|
||||
}
|
||||
|
||||
# Get the process current information
|
||||
$process = Get-Process -Id $TargetPID -ErrorAction SilentlyContinue
|
||||
|
||||
if($process) {
|
||||
$processName = $process.Name
|
||||
$cpu = [Decimal]::Round((((Get-Counter "\Process($processName*)\% Processor Time" -SampleInterval 1).CounterSamples[0].CookedValue) / $cpuCores), 2)
|
||||
$mem = $process.PagedMemorySize64 / 1MB # Convert to MB
|
||||
|
||||
# Create a custom object to hold the data
|
||||
$timeInSeconds = [math]::Round(((Get-Date) - $startTime).TotalSeconds)
|
||||
$obj = New-Object PSObject
|
||||
$obj | Add-Member -MemberType NoteProperty -Name "TimeInSecs" -Value $timeInSeconds
|
||||
$obj | Add-Member -MemberType NoteProperty -Name "CPU" -Value $cpu
|
||||
$obj | Add-Member -MemberType NoteProperty -Name "Memory" -Value $mem
|
||||
|
||||
# Add the object to the data array
|
||||
$data += $obj
|
||||
|
||||
# Add points to the chart series
|
||||
$null = $cpuSeries.Points.AddXY($timeInSeconds, $cpu)
|
||||
$null = $memSeries.Points.AddXY($timeInSeconds, $mem)
|
||||
|
||||
# Export the data to CSV
|
||||
$data | Export-Csv -Path $csvFilePath -NoTypeInformation
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
||||
# Sleep for the sample interval
|
||||
Start-Sleep -Seconds $SampleIntervalInSecs
|
||||
}
|
||||
|
||||
$chartCPU.SaveImage($chartFilePathCPU, [System.Windows.Forms.DataVisualization.Charting.ChartImageFormat]::Png)
|
||||
$chartMemory.SaveImage($chartFilePathMemory, [System.Windows.Forms.DataVisualization.Charting.ChartImageFormat]::Png)
|
17
orbit/tools/windows/profiling_process.md
Normal file
17
orbit/tools/windows/profiling_process.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Process profiling
|
||||
|
||||
To measure the CPU and memory consumption of a process in Windows, you can use the
|
||||
`process_profile_tool.ps1` tool.
|
||||
|
||||
To use this tool, you just need to pass the process ID (PID) as an argument through the `TargetPID`
|
||||
parameter. The script will run and take samples every 10 seconds by default (this can be adjusted
|
||||
using the `SampleIntervalInSecs"` parameter). The script will stop taking samples either when the
|
||||
process finishes or when a key is pressed while the script is running. As a result, the script will
|
||||
generate two PNG files in the same directory, showing the CPU and memory consumption of the process.
|
||||
|
||||
Example execution below:
|
||||
```
|
||||
PS C:\code\PoCs> . .\process_profile.ps1 -TargetPID 32652
|
||||
Key Pressed. Stopping script...
|
||||
PS C:\code\PoCs>
|
||||
```
|
Loading…
Reference in New Issue
Block a user