Merge pull request #841 from Icinga:feature/adds_new_type_info_for_checks_and_packages

Feature: Adds new [INFO] state for notice and un-checked monitoring objects

Adds new [INFO] state for `New-IcingaCheck` and `New-IcingaCheckPackage`, to allow the printing of simple informational objects as well as telling the user, which objects are currently actively checked by the plugin engine.

```powershell
icinga> Invoke-IcingaCheckCPU -Verbosity 3;

[INFO] CPU Load (All must be [OK])
\_ [INFO] Overall Load: 8.714580%
\_ [INFO] Socket #0 (All must be [OK])
   \_ [INFO] Core 0: 22.63846%
   \_ [INFO] Core 1: 11.04723%
   \_ [INFO] Core 2: 0.672020%
   \_ [INFO] Core 3: 0.500612%
   \_ [INFO] Core Total: 8.714580%
| totalload::ifw_cpu::load=8.714580%;;;0;100 0_0::ifw_cpu::load=22.63846%;;;0;100 0_1::ifw_cpu::load=11.04723%;;;0;100 0_2::ifw_cpu::load=0.672020%;;;0;100 0_3::ifw_cpu::load=0.500612%;;;0;100 0_total::ifw_cpu::load=8.714580%;;;0;100
```


```powershell
icinga> Invoke-IcingaCheckProcess -Verbosity 3 -Process  WmiApSrv -MemoryWarning '1MB' -PageFileWarning '1KiB';

[WARNING] Process Overview: 1 Warning [WARNING] WmiApSrv (All must be [OK])
\_ [WARNING] WmiApSrv (All must be [OK])
   \_ [WARNING] WmiApSrv [16476] (All must be [OK])
      \_ [INFO] CPU Usage: 0%
      \_ [WARNING] Memory Usage: Value 1.67MiB is greater than threshold 976.56KiB
      \_ [INFO] Page File Usage: 2.30KiB
      \_ [INFO] Thread Count: 5c
   \_ [INFO] WmiApSrv Summary (All must be [OK])
      \_ [INFO] CPU Usage: 0%
      \_ [INFO] Memory Usage: 1.67MiB
      \_ [INFO] Page File Usage: 2.30KiB
      \_ [INFO] Process Count: 1c
      \_ [INFO] Thread Count: 5c
| wmiapsrv::ifw_process::cpu=0%;;;0;100 wmiapsrv::ifw_process::memory=1748992B;;;0;8583315000 wmiapsrv::ifw_process::pagefile=2352B;;;0;34359740000 wmiapsrv::ifw_process::count=1c;;;; wmiapsrv::ifw_process::threads=5c;;;;
```
This commit is contained in:
Lord Hepipud 2025-12-15 16:54:32 +01:00 committed by GitHub
commit ff4a0b2bbc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 99 additions and 24 deletions

View file

@ -19,8 +19,9 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
### Enhancements ### Enhancements
* [#838](https://github.com/Icinga/icinga-powershell-framework/pull/838) Enhances Icinga for Windows to never load and user PowerShell profiles
* [#11](https://github.com/Icinga/icinga-powershell-framework/pull/11) Adds feature to update the cache for performance counter instances to keep track of system changes * [#11](https://github.com/Icinga/icinga-powershell-framework/pull/11) Adds feature to update the cache for performance counter instances to keep track of system changes
* [#838](https://github.com/Icinga/icinga-powershell-framework/pull/838) Enhances Icinga for Windows to never load and user PowerShell profiles
* [#841](https://github.com/Icinga/icinga-powershell-framework/pull/841) Adds new [INFO] state for notice and un-checked monitoring objects
## 1.13.4 (tbd) ## 1.13.4 (tbd)

View file

@ -112,7 +112,7 @@ function New-IcingaCheck()
# Override shared function # Override shared function
$IcingaCheck | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value { $IcingaCheck | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value {
param ($PluginOutput); param ($PluginOutput, $CheckOverride);
if ($this.__InLockState()) { if ($this.__InLockState()) {
return; return;
@ -140,9 +140,25 @@ function New-IcingaCheck()
$AddColon = $FALSE; $AddColon = $FALSE;
} }
[string]$PluginStatusString = $IcingaEnums.IcingaExitCodeText[$this.__CheckState];
# If our thresholds are empty, we handle this as notice object
if (-not $CheckOverride -And ([string]::IsNullOrEmpty($this.__WarningValue.Threshold.Raw) -and [string]::IsNullOrEmpty($this.__CriticalValue.Threshold.Raw))) {
# If our call sets CheckOverride, it means we could have used something like SetWarning() before
# By doing so, we actively interact with the object and therefore we should not handle it as notice object
$this.__HandleAsNoticeObject = $TRUE;
}
# Set this object to [INFO] state in case it is a notice or no thresholds are defined
# This will ensure we tell the use which check is using active checks
if ($this.__IsNoticeObject -or $this.__HandleAsNoticeObject) {
$PluginStatusString = '[INFO]';
$this.__HandleAsNoticeObject = $TRUE;
}
$this.__CheckOutput = [string]::Format( $this.__CheckOutput = [string]::Format(
'{0} {1}{2} {3}{4}', '{0} {1}{2} {3}{4}',
$IcingaEnums.IcingaExitCodeText[$this.__CheckState], $PluginStatusString,
$this.Name, $this.Name,
(&{ if ($AddColon) { return ':'; } else { return ''; } }), (&{ if ($AddColon) { return ':'; } else { return ''; } }),
$PluginThresholds, $PluginThresholds,
@ -296,7 +312,7 @@ function New-IcingaCheck()
$IcingaCheck | Add-Member -MemberType ScriptMethod -Name '__ValidateObject' -Value { $IcingaCheck | Add-Member -MemberType ScriptMethod -Name '__ValidateObject' -Value {
if ($null -eq $this.ObjectExists) { if ($null -eq $this.ObjectExists) {
$this.SetUnknown() | Out-Null; $this.SetUnknown() | Out-Null;
$this.__SetCheckOutput('The object does not exist'); $this.__SetCheckOutput('The object does not exist', $TRUE);
$this.__LockState(); $this.__LockState();
} }
} }
@ -317,7 +333,8 @@ function New-IcingaCheck()
'Usage of invalid plugin unit "{0}". Allowed units are: {1}', 'Usage of invalid plugin unit "{0}". Allowed units are: {1}',
$this.Unit, $this.Unit,
(($IcingaEnums.IcingaMeasurementUnits.Keys | Sort-Object name) -Join ', ') (($IcingaEnums.IcingaMeasurementUnits.Keys | Sort-Object name) -Join ', ')
) ),
$TRUE
); );
$this.__LockState(); $this.__LockState();
@ -395,8 +412,12 @@ function New-IcingaCheck()
param ([string]$Message, [bool]$Lock); param ([string]$Message, [bool]$Lock);
if ($this.__InLockState() -eq $FALSE) { if ($this.__InLockState() -eq $FALSE) {
# If we update the state of an object to anything, we actively tell the system
# that this is no longer a notice object
$this.__HandleAsNoticeObject = $FALSE;
$this.__CheckState = $IcingaEnums.IcingaExitCode.Ok; $this.__CheckState = $IcingaEnums.IcingaExitCode.Ok;
$this.__SetCheckOutput($Message); $this.__SetCheckOutput($Message, $TRUE);
} }
if ($Lock) { if ($Lock) {
@ -410,8 +431,11 @@ function New-IcingaCheck()
param ([string]$Message, [bool]$Lock); param ([string]$Message, [bool]$Lock);
if ($this.__InLockState() -eq $FALSE) { if ($this.__InLockState() -eq $FALSE) {
# If we update the state of an object to anything, we actively tell the system
# that this is no longer a notice object
$this.__HandleAsNoticeObject = $FALSE;
$this.__CheckState = $IcingaEnums.IcingaExitCode.Warning; $this.__CheckState = $IcingaEnums.IcingaExitCode.Warning;
$this.__SetCheckOutput($Message); $this.__SetCheckOutput($Message, $TRUE);
} }
if ($Lock) { if ($Lock) {
@ -425,7 +449,25 @@ function New-IcingaCheck()
param ([string]$Message, [bool]$Lock); param ([string]$Message, [bool]$Lock);
if ($this.__InLockState() -eq $FALSE) { if ($this.__InLockState() -eq $FALSE) {
# If we update the state of an object to anything, we actively tell the system
# that this is no longer a notice object
$this.__HandleAsNoticeObject = $FALSE;
$this.__CheckState = $IcingaEnums.IcingaExitCode.Critical; $this.__CheckState = $IcingaEnums.IcingaExitCode.Critical;
$this.__SetCheckOutput($Message, $TRUE);
}
if ($Lock) {
$this.__LockState();
}
return $this;
}
$IcingaCheck | Add-Member -MemberType ScriptMethod -Name 'SetNotice' -Value {
param ([string]$Message, [bool]$Lock);
if ($this.__InLockState() -eq $FALSE) {
$this.__IsNoticeObject = $TRUE;
$this.__SetCheckOutput($Message); $this.__SetCheckOutput($Message);
} }
@ -440,8 +482,11 @@ function New-IcingaCheck()
param ([string]$Message, [bool]$Lock); param ([string]$Message, [bool]$Lock);
if ($this.__InLockState() -eq $FALSE) { if ($this.__InLockState() -eq $FALSE) {
# If we update the state of an object to anything, we actively tell the system
# that this is no longer a notice object
$this.__HandleAsNoticeObject = $FALSE;
$this.__CheckState = $IcingaEnums.IcingaExitCode.Unknown; $this.__CheckState = $IcingaEnums.IcingaExitCode.Unknown;
$this.__SetCheckOutput($Message); $this.__SetCheckOutput($Message, $TRUE);
} }
if ($Lock) { if ($Lock) {
@ -457,7 +502,7 @@ function New-IcingaCheck()
if ($ThresholdObject.HasError) { if ($ThresholdObject.HasError) {
$this.SetUnknown() | Out-Null; $this.SetUnknown() | Out-Null;
$this.__ThresholdObject = $ThresholdObject; $this.__ThresholdObject = $ThresholdObject;
$this.__SetCheckOutput($this.__ThresholdObject.Message); $this.__SetCheckOutput($this.__ThresholdObject.Message, $TRUE);
$this.__LockState(); $this.__LockState();
return; return;
} }

View file

@ -2,17 +2,19 @@ function New-IcingaCheckBaseObject()
{ {
$IcingaCheckBaseObject = New-Object -TypeName PSObject; $IcingaCheckBaseObject = New-Object -TypeName PSObject;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name 'Name' -Value ''; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name 'Name' -Value '';
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name 'Verbose' -Value 0; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name 'Verbose' -Value 0;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Hidden' -Value $FALSE; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Hidden' -Value $FALSE;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__SkipSummary' -Value $FALSE; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__SkipSummary' -Value $FALSE;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Parent' -Value $IcingaCheckBaseObject; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Parent' -Value $IcingaCheckBaseObject;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Indention' -Value 0; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__Indention' -Value 0;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__ErrorMessage' -Value ''; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__ErrorMessage' -Value '';
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckState' -Value $IcingaEnums.IcingaExitCode.Ok; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckState' -Value $IcingaEnums.IcingaExitCode.Ok;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckCommand' -Value ''; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckCommand' -Value '';
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckOutput' -Value $null; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__CheckOutput' -Value $null;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__ObjectType' -Value 'IcingaCheckBaseObject'; $IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__IsNoticeObject' -Value $FALSE;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__HandleAsNoticeObject' -Value $FALSE;
$IcingaCheckBaseObject | Add-Member -MemberType NoteProperty -Name '__ObjectType' -Value 'IcingaCheckBaseObject';
$IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Name '__SetCheckCommand' -Value { $IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Name '__SetCheckCommand' -Value {
$CallStack = Get-PSCallStack; $CallStack = Get-PSCallStack;
@ -103,7 +105,7 @@ function New-IcingaCheckBaseObject()
} }
$IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value { $IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value {
param ($PluginOutput); param ($PluginOutput, $CheckOverride);
} }
$IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Name '__GetCheckOutput' -Value { $IcingaCheckBaseObject | Add-Member -MemberType ScriptMethod -Name '__GetCheckOutput' -Value {

View file

@ -9,9 +9,11 @@ function New-IcingaCheckPackage()
[int]$OperatorMax = -1, [int]$OperatorMax = -1,
[array]$Checks = @(), [array]$Checks = @(),
[int]$Verbose = 0, [int]$Verbose = 0,
[int]$OverrideExitCode = -1,
[switch]$IgnoreEmptyPackage = $FALSE, [switch]$IgnoreEmptyPackage = $FALSE,
[switch]$Hidden = $FALSE, [switch]$Hidden = $FALSE,
[switch]$AddSummaryHeader = $FALSE [switch]$AddSummaryHeader = $FALSE,
[switch]$IsNoticePackage = $FALSE
); );
$IcingaCheckPackage = New-IcingaCheckBaseObject; $IcingaCheckPackage = New-IcingaCheckBaseObject;
@ -28,6 +30,11 @@ function New-IcingaCheckPackage()
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'OperatorMax' -Value $OperatorMax; $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'OperatorMax' -Value $OperatorMax;
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'IgnoreEmptyPackage' -Value $IgnoreEmptyPackage; $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'IgnoreEmptyPackage' -Value $IgnoreEmptyPackage;
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'AddSummaryHeader' -Value $AddSummaryHeader; $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'AddSummaryHeader' -Value $AddSummaryHeader;
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'OverrideExitCode' -Value $OverrideExitCode;
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name 'IsNoticePackage' -Value $IsNoticePackage;
# Each check package should have at least one element which provides active checks information,
# otherwise we should display the package as INFO package
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__hasActiveChecks' -Value $FALSE;
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__Checks' -Value @(); $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__Checks' -Value @();
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__OkChecks' -Value @(); $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__OkChecks' -Value @();
$IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__WarningChecks' -Value @(); $IcingaCheckPackage | Add-Member -MemberType NoteProperty -Name '__WarningChecks' -Value @();
@ -93,7 +100,7 @@ function New-IcingaCheckPackage()
# Override shared function # Override shared function
$IcingaCheckPackage | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value { $IcingaCheckPackage | Add-Member -MemberType ScriptMethod -Force -Name '__SetCheckOutput' -Value {
param ($PluginOutput); param ($PluginOutput, $CheckOverride);
$UnknownChecks = ''; $UnknownChecks = '';
$CriticalChecks = ''; $CriticalChecks = '';
@ -140,9 +147,18 @@ function New-IcingaCheckPackage()
$HasContent = $TRUE; $HasContent = $TRUE;
} }
[string]$PluginStatusString = $IcingaEnums.IcingaExitCodeText[$this.__GetCheckState()];
# Set this object to [INFO] state in case it is a notice package or no active checks are found
# This will ensure we tell the use which check is using active checks
if ($this.IsNoticePackage -or $this.__hasActiveChecks -eq $FALSE) {
$PluginStatusString = '[INFO]';
$this.__HandleAsNoticeObject = $TRUE;
}
$this.__CheckOutput = [string]::Format( $this.__CheckOutput = [string]::Format(
'{0} {1}{2}{3}{4}{5}{6}{7}{8}', '{0} {1}{2}{3}{4}{5}{6}{7}{8}',
$IcingaEnums.IcingaExitCodeText[$this.__GetCheckState()], $PluginStatusString,
$this.Name, $this.Name,
(&{ if ($HasContent) { return ':'; } else { return ''; } }), (&{ if ($HasContent) { return ':'; } else { return ''; } }),
$CheckSummary.ToString(), $CheckSummary.ToString(),
@ -179,6 +195,13 @@ function New-IcingaCheckPackage()
$check.Compile(); $check.Compile();
# If we find at least one check which is not a notice object, we can consider
# this package as active checks package
if ($check.__HandleAsNoticeObject -eq $FALSE) {
$this.__hasActiveChecks = $TRUE;
$this.__HandleAsNoticeObject = $FALSE;
}
if ($check.__IsHidden() -Or $check.__NoHeaderReport()) { if ($check.__IsHidden() -Or $check.__NoHeaderReport()) {
continue; continue;
} }
@ -317,6 +340,10 @@ function New-IcingaCheckPackage()
return ''; return '';
} }
if ($this.IsNoticePackage) {
return '';
}
if ($this.OperatorAnd) { if ($this.OperatorAnd) {
return ' (All must be [OK])'; return ' (All must be [OK])';
} }