diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index e170c46f..8e14916a 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -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) diff --git a/lib/provider/assets/cpu/Get-IcingaProviderDataValuesCpu.psm1 b/lib/provider/assets/cpu/Get-IcingaProviderDataValuesCpu.psm1 index dfed7c6d..0455b2f4 100644 --- a/lib/provider/assets/cpu/Get-IcingaProviderDataValuesCpu.psm1 +++ b/lib/provider/assets/cpu/Get-IcingaProviderDataValuesCpu.psm1 @@ -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; } diff --git a/lib/provider/assets/cpu/New-IcingaProviderFilterDataCpu.psm1 b/lib/provider/assets/cpu/New-IcingaProviderFilterDataCpu.psm1 new file mode 100644 index 00000000..b0ea0119 --- /dev/null +++ b/lib/provider/assets/cpu/New-IcingaProviderFilterDataCpu.psm1 @@ -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; +}