icinga-powershell-framework/lib/provider/assets/process/Get-IcingaProviderDataValuesProcess.psm1

154 lines
10 KiB
PowerShell

function Get-IcingaProviderDataValuesProcess()
{
param (
[array]$IncludeFilter = @(),
[array]$ExcludeFilter = @(),
[switch]$IncludeDetails = $FALSE
);
# Fetch all required process information
$ProviderName = 'Process'
$ProcessData = New-IcingaProviderObject -Name $ProviderName;
[array]$ProcessInformation = Get-IcingaWindowsInformation Win32_Process;
[array]$ProcessPerfDataList = Get-IcingaWindowsInformation Win32_PerfFormattedData_PerfProc_Process;
[hashtable]$CPUProcessCache = @{ };
[hashtable]$MEMProcessCache = @{ };
# Read our process data and build our metrics object
foreach ($entry in $ProcessInformation) {
[string]$ProcessName = $entry.Name.Replace('.exe', '');
[int]$ProcessId = [int]$entry.ProcessId;
if ((Test-IcingaArrayFilter -InputObject $ProcessName -Include $IncludeFilter -Exclude $ExcludeFilter) -eq $FALSE) {
continue;
}
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics -Name $ProcessName) -eq $FALSE) {
$ProcessData.Metrics | Add-Member -MemberType NoteProperty -Name $ProcessName -Value (New-Object PSCustomObject);
$ProcessData.Metrics.$ProcessName | Add-Member -MemberType NoteProperty -Name 'List' -Value (New-Object PSCustomObject);
$ProcessData.Metrics.$ProcessName | Add-Member -MemberType NoteProperty -Name 'Total' -Value (New-Object PSCustomObject);
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'PageFileUsage' -Value 0;
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'ThreadCount' -Value 0;
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'WorkingSetSize' -Value 0;
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'ProcessCount' -Value 0;
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
}
# Detail for each single Process
$ProcessData.Metrics.$ProcessName.List | Add-Member -MemberType NoteProperty -Name $ProcessId -Value (New-Object PSCustomObject);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $ProcessName;
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessName' -Value ([string]$entry.Name);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $ProcessId;
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'Priority' -Value ([int]$entry.Priority);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'PageFileUsage' -Value ([decimal]$entry.PageFileUsage);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ThreadCount' -Value ([int]$entry.ThreadCount);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'KernelModeTime' -Value ([decimal]$entry.KernelModeTime);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'UserModeTime' -Value ([decimal]$entry.UserModeTime);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'WorkingSetSize' -Value ([decimal]$entry.WorkingSetSize);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CommandLine' -Value ([string]$entry.CommandLine);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
# Total data for all processes with a given name
$ProcessData.Metrics.$ProcessName.Total.PageFileUsage += ([decimal]$entry.PageFileUsage);
$ProcessData.Metrics.$ProcessName.Total.ThreadCount += ([int]$entry.ThreadCount);
$ProcessData.Metrics.$ProcessName.Total.WorkingSetSize += ([decimal]$entry.WorkingSetSize);
$ProcessData.Metrics.$ProcessName.Total.ProcessCount += 1;
}
# Process all process performance metrics and add memory and cpu usage to the correct process id
foreach ($entry in $ProcessPerfDataList) {
[string]$ProcessName = $entry.Name;
[int]$ProcessId = [int]$entry.IDProcess;
if ($ProcessName.Contains('#')) {
$ProcessName = $ProcessName.Substring(0, $ProcessName.IndexOf('#'));
}
if ((Test-IcingaArrayFilter -InputObject $ProcessName -Include $IncludeFilter -Exclude $ExcludeFilter) -eq $FALSE) {
continue;
}
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics -Name $ProcessName) -eq $FALSE) {
continue;
}
# Add a cache for our Process Data with all CPU loads for every single Process Id
$CPUProcessCache.Add([string]::Format('{0}|{1}', $ProcessName, [string]$ProcessId), [int]$entry.PercentProcessorTime);
$MEMProcessCache.Add([string]::Format('{0}|{1}', $ProcessName, [string]$ProcessId), [decimal]$entry.WorkingSetPrivate);
# Just in case a process id is not present, we should ensure to add it to prevent exceptions
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics.$ProcessName.List -Name $ProcessId) -eq $FALSE) {
$ProcessData.Metrics.$ProcessName.List | Add-Member -MemberType NoteProperty -Name $ProcessId -Value (New-Object PSCustomObject);
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
}
$ProcessData.Metrics.$ProcessName.List.$ProcessId.CpuUsage = [int]$entry.PercentProcessorTime;
$ProcessData.Metrics.$ProcessName.List.$ProcessId.MemoryUsage = [decimal]$entry.WorkingSetPrivate;
$ProcessData.Metrics.$ProcessName.Total.CpuUsage += [int]$entry.PercentProcessorTime;
$ProcessData.Metrics.$ProcessName.Total.MemoryUsage += [decimal]$entry.WorkingSetPrivate;
}
# Generaet a "hot" object for our 10 most CPU and Memory consuming process objects
$ProcessData.Metadata | Add-Member -MemberType NoteProperty -Name 'Hot' -Value (New-Object PSCustomObject);
$ProcessData.Metadata.Hot | Add-Member -MemberType NoteProperty -Name 'Cpu' -Value (New-Object PSCustomObject);
$ProcessData.Metadata.Hot | Add-Member -MemberType NoteProperty -Name 'Memory' -Value (New-Object PSCustomObject);
[array]$TopCPUUsage = $CPUProcessCache.GetEnumerator() | Sort-Object Value -Descending;
[array]$TopMEMUsage = $MEMProcessCache.GetEnumerator() | Sort-Object Value -Descending;
[int]$IterationIndex = 0;
while ($IterationIndex -lt 10) {
if ($TopCPUUsage.Count -gt 0 -And (($TopCPUUsage.Count - 1) -ge $IterationIndex )) {
if ($TopCPUUsage.Count -gt 1) {
[string]$CPUProcessName = $TopCPUUsage.Key[$IterationIndex].Split('|')[0];
[int]$CPUProcessId = $TopCPUUsage.Key[$IterationIndex].Split('|')[1];
[int]$CPUUsage = $TopCPUUsage.Value[$IterationIndex];
} else {
[string]$CPUProcessName = $TopCPUUsage.Key.Split('|')[0];
[int]$CPUProcessId = $TopCPUUsage.Key.Split('|')[1];
[int]$CPUUsage = $TopCPUUsage.Value;
}
if ($TopCPUUsage.Value[$IterationIndex] -gt 0) {
$ProcessData.Metadata.Hot.Cpu | Add-Member -MemberType NoteProperty -Name $CPUProcessId -Value (New-Object PSCustomObject);
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $CPUProcessName;
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $CPUProcessId;
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value $CPUUsage;
}
}
if ($TopMEMUsage.Count -gt 0 -And (($TopMEMUsage.Count - 1) -ge $IterationIndex )) {
if ($TopMEMUsage.Count -gt 1) {
[string]$MEMProcessName = $TopMEMUsage.Key[$IterationIndex].Split('|')[0];
[int]$MEPProcessId = $TopMEMUsage.Key[$IterationIndex].Split('|')[1];
[decimal]$MemoryUsage = $TopMEMUsage.Value[$IterationIndex];
} else {
[string]$MEMProcessName = $TopMEMUsage.Key.Split('|')[0];
[int]$MEPProcessId = $TopMEMUsage.Key.Split('|')[1];
[int]$MemoryUsage = $TopMEMUsage.Value;
}
if ($TopMEMUsage.Value[$IterationIndex] -gt 0) {
$ProcessData.Metadata.Hot.Memory | Add-Member -MemberType NoteProperty -Name $MEPProcessId -Value (New-Object PSCustomObject);
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $MEMProcessName;
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $MEPProcessId;
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value $MemoryUsage;
}
}
$IterationIndex += 1;
}
$CPUProcessCache = $null;
$MEMProcessCache = $null;
$ProcessInformation = $null;
$ProcessPerfDataList = $null;
$TopCPUUsage = $null;
$TopMEMUsage = $null;
return $ProcessData;
}