Adds option to CPU provider to limit thread usage to 100%

This commit is contained in:
Lord Hepipud 2024-07-10 16:29:56 +02:00
parent ca3be7665a
commit f2343fb35d
3 changed files with 115 additions and 84 deletions

View file

@ -21,6 +21,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
* [#732](https://github.com/Icinga/icinga-powershell-framework/pull/732) Adds support for TLS 1.3 and improves startup response
* [#735](https://github.com/Icinga/icinga-powershell-framework/pull/735) Adds support to provide occuring problem event id's for the Eventlog and corresponding acknowledgement id's, providing an indicator if certain issues are resolved or still present
* [#742](https://github.com/Icinga/icinga-powershell-framework/pull/742) Adds support for the CPU provider to limit the CPU usage to 100% for each thread
## 1.12.3 (2024-04-24)

View file

@ -1,94 +1,20 @@
function Get-IcingaProviderDataValuesCpu()
{
param (
[array]$IncludeFilter = @(),
[array]$ExcludeFilter = @(),
[switch]$IncludeDetails = $FALSE
[array]$IncludeFilter = @(),
[array]$ExcludeFilter = @(),
[hashtable]$ProviderFilter = @(),
[switch]$IncludeDetails = $FALSE
);
$CpuData = New-IcingaProviderObject -Name 'Cpu';
$CpuCounter = New-IcingaPerformanceCounterArray '\Processor Information(*)\% Processor Utility';
$CounterStructure = New-IcingaPerformanceCounterStructure -CounterCategory 'Processor Information' -PerformanceCounterHash $CpuCounter;
[int]$TotalCpuThreads = 0;
[decimal]$TotalCpuLoad = 0;
[int]$SocketCount = 0;
[hashtable]$SocketList = @{ };
$CpuData = New-IcingaProviderObject -Name 'Cpu';
[hashtable]$FilterObject = Get-IcingaProviderFilterData -ProviderName 'Cpu' -ProviderFilter $ProviderFilter;
foreach ($core in $CounterStructure.Keys) {
[string]$Socket = $core.Split(',')[0];
[string]$CoreId = $core.Split(',')[1];
[string]$SocketName = [string]::Format('Socket #{0}', $Socket);
$CpuData.Metrics = $FilterObject.Cpu.Query.Metrics;
$CpuData.MetricsOverTime = $FilterObject.Cpu.Query.MetricsOverTime;
$CpuData.Metadata = $FilterObject.Cpu.Query.Metadata;
if ($Socket -eq '_Total' -Or $CoreId -eq '_Total') {
continue;
}
if ($SocketList.ContainsKey($SocketName) -eq $FALSE) {
$SocketList.Add(
$SocketName,
@{
'ThreadCount' = 0;
'TotalLoad' = 0;
}
);
}
if ((Test-PSCustomObjectMember -PSObject $CpuData.Metrics -Name $SocketName) -eq $FALSE) {
$CpuData.Metrics | Add-Member -MemberType NoteProperty -Name $SocketName -Value (New-Object PSCustomObject);
}
[decimal]$CoreLoad = $CounterStructure[$core]['% Processor Utility'].value;
$CpuData.Metrics.$SocketName | Add-Member -MemberType NoteProperty -Name $CoreId -Value $CoreLoad;
$CpuData.MetricsOverTime.MetricContainer | Add-Member -MemberType NoteProperty -Name $SocketName -Value $null -Force;
$SocketList[$SocketName].ThreadCount += 1;
$SocketList[$SocketName].TotalLoad += $CoreLoad;
}
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'Sockets' -Value (New-Object PSCustomObject);
foreach ($entry in $SocketList.Keys) {
$SocketList[$entry].TotalLoad = $SocketList[$entry].TotalLoad / $SocketList[$entry].ThreadCount;
$TotalCpuLoad += $SocketList[$entry].TotalLoad;
$TotalCpuThreads += $SocketList[$entry].ThreadCount;
$SocketCount += 1;
$CpuData.Metadata.Sockets | Add-Member -MemberType NoteProperty -Name $entry -Value (New-Object PSCustomObject);
$CpuData.Metadata.Sockets.$entry | Add-Member -MemberType NoteProperty -Name 'Threads' -Value $SocketList[$entry].ThreadCount;
$CpuData.Metrics.$entry | Add-Member -MemberType NoteProperty -Name 'Total' -Value $SocketList[$entry].TotalLoad;
}
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalLoad' -Value ($TotalCpuLoad / $SocketCount);
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalLoadSum' -Value $TotalCpuLoad;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalThreads' -Value $TotalCpuThreads;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'CoreDigits' -Value ([string]$TotalCpuThreads).Length;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'CoreDetails' -Value (New-Object PSCustomObject);
if ($IncludeDetails) {
[array]$CPUCIMData = Get-IcingaWindowsInformation Win32_Processor;
foreach ($cpu in $CPUCIMData) {
if ((Test-PSCustomObjectMember -PSObject $CpuData.Metadata.CoreDetails -Name $cpu.DeviceID) -eq $FALSE) {
$CpuData.Metadata.CoreDetails | Add-Member -MemberType NoteProperty -Name $cpu.DeviceID -Value (New-Object PSCustomObject);
}
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Architecture' -Value $cpu.Architecture;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'ProcessorType' -Value $cpu.ProcessorType;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'StatusInfo' -Value $cpu.StatusInfo;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Family' -Value $cpu.Family;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'CurrentVoltage' -Value $cpu.CurrentVoltage;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L3CacheSize' -Value $cpu.L3CacheSize;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L2CacheSize' -Value $cpu.L2CacheSize;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L2CacheSpeed' -Value $cpu.L2CacheSpeed;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'VoltageCaps' -Value $cpu.VoltageCaps;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'CurrentClockSpeed' -Value $cpu.CurrentClockSpeed;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Caption' -Value $cpu.Caption;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Name' -Value $cpu.Name;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'SerialNumber' -Value $cpu.SerialNumber;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Manufacturer' -Value $cpu.Manufacturer;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'AddressWidth' -Value $cpu.AddressWidth;
}
}
$FilterObject = $null;
return $CpuData;
}

View file

@ -0,0 +1,104 @@
<#
.ROLE
Query
#>
function New-IcingaProviderFilterDataCpu()
{
param (
[switch]$Limit100Percent = $FALSE,
[switch]$IncludeDetails = $FALSE
);
$CpuData = New-IcingaProviderObject -Name 'Cpu';
$CpuCounter = New-IcingaPerformanceCounterArray '\Processor Information(*)\% Processor Utility';
$CounterStructure = New-IcingaPerformanceCounterStructure -CounterCategory 'Processor Information' -PerformanceCounterHash $CpuCounter;
[int]$TotalCpuThreads = 0;
[decimal]$TotalCpuLoad = 0;
[int]$SocketCount = 0;
[hashtable]$SocketList = @{ };
foreach ($currentcore in $CounterStructure.Keys) {
[string]$Socket = $currentcore.Split(',')[0];
[string]$CoreId = $currentcore.Split(',')[1];
[string]$SocketName = [string]::Format('Socket #{0}', $Socket);
if ($Socket -eq '_Total' -Or $CoreId -eq '_Total') {
continue;
}
if ($SocketList.ContainsKey($SocketName) -eq $FALSE) {
$SocketList.Add(
$SocketName,
@{
'ThreadCount' = 0;
'TotalLoad' = 0;
}
);
}
if ((Test-PSCustomObjectMember -PSObject $CpuData.Metrics -Name $SocketName) -eq $FALSE) {
$CpuData.Metrics | Add-Member -MemberType NoteProperty -Name $SocketName -Value (New-Object PSCustomObject);
}
[decimal]$CoreLoad = $CounterStructure[$currentcore]['% Processor Utility'].value;
if ($Limit100Percent) {
if ($CoreLoad -gt 100) {
$CoreLoad = 100;
}
}
$CpuData.Metrics.$SocketName | Add-Member -MemberType NoteProperty -Name $CoreId -Value $CoreLoad;
$CpuData.MetricsOverTime.MetricContainer | Add-Member -MemberType NoteProperty -Name $SocketName -Value $null -Force;
$SocketList[$SocketName].ThreadCount += 1;
$SocketList[$SocketName].TotalLoad += $CoreLoad;
}
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'Sockets' -Value (New-Object PSCustomObject);
foreach ($entry in $SocketList.Keys) {
$SocketList[$entry].TotalLoad = $SocketList[$entry].TotalLoad / $SocketList[$entry].ThreadCount;
$TotalCpuLoad += $SocketList[$entry].TotalLoad;
$TotalCpuThreads += $SocketList[$entry].ThreadCount;
$SocketCount += 1;
$CpuData.Metadata.Sockets | Add-Member -MemberType NoteProperty -Name $entry -Value (New-Object PSCustomObject);
$CpuData.Metadata.Sockets.$entry | Add-Member -MemberType NoteProperty -Name 'Threads' -Value $SocketList[$entry].ThreadCount;
$CpuData.Metrics.$entry | Add-Member -MemberType NoteProperty -Name 'Total' -Value $SocketList[$entry].TotalLoad;
}
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalLoad' -Value ($TotalCpuLoad / $SocketCount);
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalLoadSum' -Value $TotalCpuLoad;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'TotalThreads' -Value $TotalCpuThreads;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'CoreDigits' -Value ([string]$TotalCpuThreads).Length;
$CpuData.Metadata | Add-Member -MemberType NoteProperty -Name 'CoreDetails' -Value (New-Object PSCustomObject);
if ($IncludeDetails) {
[array]$CPUCIMData = Get-IcingaWindowsInformation Win32_Processor;
foreach ($cpu in $CPUCIMData) {
if ((Test-PSCustomObjectMember -PSObject $CpuData.Metadata.CoreDetails -Name $cpu.DeviceID) -eq $FALSE) {
$CpuData.Metadata.CoreDetails | Add-Member -MemberType NoteProperty -Name $cpu.DeviceID -Value (New-Object PSCustomObject);
}
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Architecture' -Value $cpu.Architecture;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'ProcessorType' -Value $cpu.ProcessorType;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'StatusInfo' -Value $cpu.StatusInfo;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Family' -Value $cpu.Family;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'CurrentVoltage' -Value $cpu.CurrentVoltage;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L3CacheSize' -Value $cpu.L3CacheSize;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L2CacheSize' -Value $cpu.L2CacheSize;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'L2CacheSpeed' -Value $cpu.L2CacheSpeed;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'VoltageCaps' -Value $cpu.VoltageCaps;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'CurrentClockSpeed' -Value $cpu.CurrentClockSpeed;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Caption' -Value $cpu.Caption;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Name' -Value $cpu.Name;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'SerialNumber' -Value $cpu.SerialNumber;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'Manufacturer' -Value $cpu.Manufacturer;
$CpuData.Metadata.CoreDetails.($cpu.DeviceID) | Add-Member -MemberType NoteProperty -Name 'AddressWidth' -Value $cpu.AddressWidth;
}
}
return $CpuData;
}