Skip to content

Commit 91b9b4b

Browse files
committed
Adds new provider for fetching process information
1 parent 5305f7e commit 91b9b4b

File tree

5 files changed

+171
-5
lines changed

5 files changed

+171
-5
lines changed

lib/icinga/plugin/New-IcingaCheck.psm1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ function New-IcingaCheck()
2121
$IcingaCheck.Name = $Name;
2222
$IcingaCheck.__ObjectType = 'IcingaCheck';
2323

24-
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'Value' -Value $Value;
24+
# Ensure we always set our current value to 0 in case it is null and we set a unit, to prevent conversion exceptions
25+
if ([string]::IsNullOrEmpty($Unit) -eq $FALSE -And $null -eq $Value) {
26+
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'Value' -Value 0;
27+
} else {
28+
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'Value' -Value $Value;
29+
}
30+
2531
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'BaseValue' -Value $BaseValue;
2632
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'Unit' -Value $Unit;
2733
$IcingaCheck | Add-Member -MemberType NoteProperty -Name 'MetricIndex' -Value $MetricIndex;

lib/provider/assets/cpu/Get-IcingaProviderDataValuesCpu.psm1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
function Get-IcingaProviderDataValuesCpu()
22
{
33
param (
4+
[array]$IncludeFilter = @(),
5+
[array]$ExcludeFilter = @(),
46
[switch]$IncludeDetails = $FALSE
57
);
68

lib/provider/assets/hyperv/Get-IcingaProviderDataValuesHyperV.psm1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
function Get-IcingaProviderDataValuesHyperV()
22
{
33
param (
4+
[array]$IncludeFilter = @(),
5+
[array]$ExcludeFilter = @(),
46
[switch]$IncludeDetails = $FALSE
57
);
68

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
function Get-IcingaProviderDataValuesProcess()
2+
{
3+
param (
4+
[array]$IncludeFilter = @(),
5+
[array]$ExcludeFilter = @(),
6+
[switch]$IncludeDetails = $FALSE
7+
);
8+
9+
# Fetch all required process information
10+
$ProviderName = 'Process'
11+
$ProcessData = New-IcingaProviderObject -Name $ProviderName;
12+
[array]$ProcessInformation = Get-IcingaWindowsInformation Win32_Process;
13+
[array]$ProcessPerfDataList = Get-IcingaWindowsInformation Win32_PerfFormattedData_PerfProc_Process;
14+
[hashtable]$CPUProcessCache = @{ };
15+
[hashtable]$MEMProcessCache = @{ };
16+
17+
# Read our process data and build our metrics object
18+
foreach ($entry in $ProcessInformation) {
19+
[string]$ProcessName = $entry.Name.Replace('.exe', '');
20+
[int]$ProcessId = [int]$entry.ProcessId;
21+
22+
if ((Test-IcingaArrayFilter -InputObject $ProcessName -Include $IncludeFilter -Exclude $ExcludeFilter) -eq $FALSE) {
23+
continue;
24+
}
25+
26+
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics -Name $ProcessName) -eq $FALSE) {
27+
$ProcessData.Metrics | Add-Member -MemberType NoteProperty -Name $ProcessName -Value (New-Object PSCustomObject);
28+
$ProcessData.Metrics.$ProcessName | Add-Member -MemberType NoteProperty -Name 'List' -Value (New-Object PSCustomObject);
29+
$ProcessData.Metrics.$ProcessName | Add-Member -MemberType NoteProperty -Name 'Total' -Value (New-Object PSCustomObject);
30+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'PageFileUsage' -Value 0;
31+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'ThreadCount' -Value 0;
32+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'WorkingSetSize' -Value 0;
33+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'ProcessCount' -Value 0;
34+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
35+
$ProcessData.Metrics.$ProcessName.Total | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
36+
}
37+
38+
# Detail for each single Process
39+
$ProcessData.Metrics.$ProcessName.List | Add-Member -MemberType NoteProperty -Name $ProcessId -Value (New-Object PSCustomObject);
40+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $ProcessName;
41+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessName' -Value ([string]$entry.Name);
42+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $ProcessId;
43+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'Priority' -Value ([int]$entry.Priority);
44+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'PageFileUsage' -Value ([decimal]$entry.PageFileUsage);
45+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'ThreadCount' -Value ([int]$entry.ThreadCount);
46+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'KernelModeTime' -Value ([decimal]$entry.KernelModeTime);
47+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'UserModeTime' -Value ([decimal]$entry.UserModeTime);
48+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'WorkingSetSize' -Value ([decimal]$entry.WorkingSetSize);
49+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CommandLine' -Value ([string]$entry.CommandLine);
50+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
51+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
52+
53+
# Total data for all processes with a given name
54+
$ProcessData.Metrics.$ProcessName.Total.PageFileUsage += ([decimal]$entry.PageFileUsage);
55+
$ProcessData.Metrics.$ProcessName.Total.ThreadCount += ([int]$entry.ThreadCount);
56+
$ProcessData.Metrics.$ProcessName.Total.WorkingSetSize += ([decimal]$entry.WorkingSetSize);
57+
$ProcessData.Metrics.$ProcessName.Total.ProcessCount += 1;
58+
}
59+
60+
# Process all process performance metrics and add memory and cpu usage to the correct process id
61+
foreach ($entry in $ProcessPerfDataList) {
62+
[string]$ProcessName = $entry.Name;
63+
[int]$ProcessId = [int]$entry.IDProcess;
64+
65+
if ($ProcessName.Contains('#')) {
66+
$ProcessName = $ProcessName.Substring(0, $ProcessName.IndexOf('#'));
67+
}
68+
69+
if ((Test-IcingaArrayFilter -InputObject $ProcessName -Include $IncludeFilter -Exclude $ExcludeFilter) -eq $FALSE) {
70+
continue;
71+
}
72+
73+
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics -Name $ProcessName) -eq $FALSE) {
74+
continue;
75+
}
76+
77+
# Add a cache for our Process Data with all CPU loads for every single Process Id
78+
$CPUProcessCache.Add([string]::Format('{0}|{1}', $ProcessName, [string]$ProcessId), [int]$entry.PercentProcessorTime);
79+
$MEMProcessCache.Add([string]::Format('{0}|{1}', $ProcessName, [string]$ProcessId), [decimal]$entry.WorkingSetPrivate);
80+
81+
# Just in case a process id is not present, we should ensure to add it to prevent exceptions
82+
if ((Test-PSCustomObjectMember -PSObject $ProcessData.Metrics.$ProcessName.List -Name $ProcessId) -eq $FALSE) {
83+
$ProcessData.Metrics.$ProcessName.List | Add-Member -MemberType NoteProperty -Name $ProcessId -Value (New-Object PSCustomObject);
84+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value 0;
85+
$ProcessData.Metrics.$ProcessName.List.$ProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value 0;
86+
}
87+
88+
$ProcessData.Metrics.$ProcessName.List.$ProcessId.CpuUsage = [int]$entry.PercentProcessorTime;
89+
$ProcessData.Metrics.$ProcessName.List.$ProcessId.MemoryUsage = [decimal]$entry.WorkingSetPrivate;
90+
$ProcessData.Metrics.$ProcessName.Total.CpuUsage += [int]$entry.PercentProcessorTime;
91+
$ProcessData.Metrics.$ProcessName.Total.MemoryUsage += [decimal]$entry.WorkingSetPrivate;
92+
}
93+
94+
# Generaet a "hot" object for our 10 most CPU and Memory consuming process objects
95+
$ProcessData.Metadata | Add-Member -MemberType NoteProperty -Name 'Hot' -Value (New-Object PSCustomObject);
96+
$ProcessData.Metadata.Hot | Add-Member -MemberType NoteProperty -Name 'Cpu' -Value (New-Object PSCustomObject);
97+
$ProcessData.Metadata.Hot | Add-Member -MemberType NoteProperty -Name 'Memory' -Value (New-Object PSCustomObject);
98+
99+
[array]$TopCPUUsage = $CPUProcessCache.GetEnumerator() | Sort-Object Value -Descending;
100+
[array]$TopMEMUsage = $MEMProcessCache.GetEnumerator() | Sort-Object Value -Descending;
101+
[int]$IterationIndex = 0;
102+
103+
while ($IterationIndex -lt 10) {
104+
if ($TopCPUUsage.Count -gt 0 -And (($TopCPUUsage.Count - 1) -ge $IterationIndex )) {
105+
106+
if ($TopCPUUsage.Count -gt 1) {
107+
[string]$CPUProcessName = $TopCPUUsage.Key[$IterationIndex].Split('|')[0];
108+
[int]$CPUProcessId = $TopCPUUsage.Key[$IterationIndex].Split('|')[1];
109+
[int]$CPUUsage = $TopCPUUsage.Value[$IterationIndex];
110+
} else {
111+
[string]$CPUProcessName = $TopCPUUsage.Key.Split('|')[0];
112+
[int]$CPUProcessId = $TopCPUUsage.Key.Split('|')[1];
113+
[int]$CPUUsage = $TopCPUUsage.Value;
114+
}
115+
116+
if ($TopCPUUsage.Value[$IterationIndex] -gt 0) {
117+
$ProcessData.Metadata.Hot.Cpu | Add-Member -MemberType NoteProperty -Name $CPUProcessId -Value (New-Object PSCustomObject);
118+
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $CPUProcessName;
119+
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $CPUProcessId;
120+
$ProcessData.Metadata.Hot.Cpu.$CPUProcessId | Add-Member -MemberType NoteProperty -Name 'CpuUsage' -Value $CPUUsage;
121+
}
122+
}
123+
124+
if ($TopMEMUsage.Count -gt 0 -And (($TopMEMUsage.Count - 1) -ge $IterationIndex )) {
125+
if ($TopMEMUsage.Count -gt 1) {
126+
[string]$MEMProcessName = $TopMEMUsage.Key[$IterationIndex].Split('|')[0];
127+
[int]$MEPProcessId = $TopMEMUsage.Key[$IterationIndex].Split('|')[1];
128+
[decimal]$MemoryUsage = $TopMEMUsage.Value[$IterationIndex];
129+
} else {
130+
[string]$MEMProcessName = $TopMEMUsage.Key.Split('|')[0];
131+
[int]$MEPProcessId = $TopMEMUsage.Key.Split('|')[1];
132+
[int]$MemoryUsage = $TopMEMUsage.Value;
133+
}
134+
135+
if ($TopMEMUsage.Value[$IterationIndex] -gt 0) {
136+
$ProcessData.Metadata.Hot.Memory | Add-Member -MemberType NoteProperty -Name $MEPProcessId -Value (New-Object PSCustomObject);
137+
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'Name' -Value $MEMProcessName;
138+
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'ProcessId' -Value $MEPProcessId;
139+
$ProcessData.Metadata.Hot.Memory.$MEPProcessId | Add-Member -MemberType NoteProperty -Name 'MemoryUsage' -Value $MemoryUsage;
140+
}
141+
}
142+
143+
$IterationIndex += 1;
144+
}
145+
146+
$CPUProcessCache = $null;
147+
$MEMProcessCache = $null;
148+
$ProcessInformation = $null;
149+
$ProcessPerfDataList = $null;
150+
$TopCPUUsage = $null;
151+
$TopMEMUsage = $null;
152+
153+
return $ProcessData;
154+
}

lib/provider/core/Get-IcingaProviderData.psm1

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
function Get-IcingaProviderData()
22
{
33
param (
4-
[array]$Name = ''
4+
[array]$Name = '',
5+
[array]$IncludeFilter = @(),
6+
[array]$ExcludeFilter = @(),
7+
[switch]$IncludeDetails = $FALSE
58
);
69

710
[hashtable]$ProviderData = @{ };
@@ -24,9 +27,8 @@ function Get-IcingaProviderData()
2427
continue;
2528
}
2629

27-
$ProviderCmd = $ProviderDataList[0];
28-
29-
$ProviderContent = (& $ProviderCmd -IncludeDetails);
30+
$ProviderCmd = $ProviderDataList[0];
31+
$ProviderContent = (& $ProviderCmd -IncludeDetails:$IncludeDetails -IncludeFilter $IncludeFilter -ExcludeFilter $ExcludeFilter);
3032

3133
if ($ProviderData.ContainsKey($ProviderContent.Name) -eq $FALSE) {
3234
$ProviderData.Add($ProviderContent.Name, $ProviderContent);

0 commit comments

Comments
 (0)