From 64fb6d44609a60113de9b1e8d6c6ed8aa2927d60 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 18:17:39 +0100 Subject: [PATCH] Improves plugin check output and visibility --- lib/icinga/plugin/New-IcingaCheck.psm1 | 87 +++++++--- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 151 +++++++++++++----- 2 files changed, 177 insertions(+), 61 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 2524d77..3c7ee48 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -15,28 +15,33 @@ function New-IcingaCheck() ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); - $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; - $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; - $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; - $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; - $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'okchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'warningchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticalchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknownchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); + $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; + $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; + $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; + $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; + $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'checkpackage' -value $FALSE; $Check | Add-Member -membertype ScriptMethod -name 'HandleDaemon' -value { # Only apply this once the checkcommand is set @@ -77,6 +82,18 @@ function New-IcingaCheck() $this.HandleDaemon(); } + $Check | Add-Member -membertype ScriptMethod -name 'GetWarnings' -value { + return $this.warningchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetCriticals' -value { + return $this.criticalchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetUnknowns' -value { + return $this.unknownchecks; + } + $Check | Add-Member -membertype ScriptMethod -name 'WarnOutOfRange' -value { param($warning); @@ -503,7 +520,7 @@ function New-IcingaCheck() param($message, [int]$exitcode); [string]$outputMessage = [string]::Format( - '{0}: {1}', + '{0} {1}', $IcingaEnums.IcingaExitCodeText[$exitcode], $message ); @@ -529,6 +546,27 @@ function New-IcingaCheck() } } + $Check | Add-Member -membertype ScriptMethod -name 'AddCheckStateArrays' -value { + switch ([int]$this.exitcode) { + $IcingaEnums.IcingaExitCode.Ok { + $this.okchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Warning { + $this.warningchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Critical { + $this.criticalchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Unknown { + $this.unknownchecks += $this.name; + break; + }; + } + } + $Check | Add-Member -membertype ScriptMethod -name 'PrintOkMessages' -value { param([string]$spaces); $this.OutputMessageArray($this.oks, $spaces); @@ -649,6 +687,7 @@ function New-IcingaCheck() $this.AddOkOutput(); $this.compiled = $TRUE; + $this.AddCheckStateArrays(); } $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { @@ -665,6 +704,8 @@ function New-IcingaCheck() $this.PrintOutputMessages(); } + $this.AddCheckStateArrays(); + return $this.exitcode; } diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 9c2b33e..f941c05 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -16,20 +16,25 @@ function New-IcingaCheckPackage() ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; - $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; - $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; - $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; - $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; - $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; - $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; + $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; + $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; + $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; + $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; + $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; + $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'headermsg' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'checkpackage' -value $TRUE; + $Check | Add-Member -membertype NoteProperty -name 'warningchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticalchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknownchecks' -value @(); $Check | Add-Member -membertype ScriptMethod -name 'Initialise' -value { foreach ($check in $this.checks) { @@ -68,6 +73,30 @@ function New-IcingaCheckPackage() $this.checks += $check; } + $Check | Add-Member -membertype ScriptMethod -name 'GetWarnings' -value { + foreach ($check in $this.checks) { + $this.warningchecks += $check.GetWarnings(); + } + + return $this.warningchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetCriticals' -value { + foreach ($check in $this.checks) { + $this.criticalchecks += $check.GetCriticals(); + } + + return $this.criticalchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetUnknowns' -value { + foreach ($check in $this.checks) { + $this.unknownchecks += $check.GetUnknowns(); + } + + return $this.unknownchecks; + } + $Check | Add-Member -membertype ScriptMethod -name 'AssignCheckCommand' -value { param($CheckCommand); @@ -219,13 +248,19 @@ function New-IcingaCheckPackage() } } - $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { - if ($this.hidden) { + $Check | Add-Member -membertype ScriptMethod -name 'PrintOutputMessageSorted' -value { + param($skipHidden, $skipExitCode); + + if ($this.hidden -And $skipHidden) { return; } [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { + if ([int]$check.exitcode -eq $skipExitCode -And $skipExitCode -ne -1) { + continue; + } + if ($MessageOrdering.ContainsKey($check.Name) -eq $FALSE) { $MessageOrdering.Add($check.name, $check); } else { @@ -248,31 +283,24 @@ function New-IcingaCheckPackage() } } + $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { + $this.PrintOutputMessageSorted($TRUE, -1); + } + $Check | Add-Member -membertype ScriptMethod -name 'PrintAllMessages' -value { $this.WritePackageOutputStatus(); $this.WriteAllOutput(); } $Check | Add-Member -membertype ScriptMethod -name 'WriteCheckErrors' -value { - [hashtable]$MessageOrdering = @{}; - foreach ($check in $this.checks) { - if ([int]$check.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { - $MessageOrdering.Add($check.name, $check); - } - } - - $SortedArray = $MessageOrdering.GetEnumerator() | Sort-Object name; - - foreach ($entry in $SortedArray) { - $entry.Value.PrintAllMessages(); - } + $this.PrintOutputMessageSorted($FALSE, $IcingaEnums.IcingaExitCode.Ok); } $Check | Add-Member -membertype ScriptMethod -name 'PrintNoChecksConfigured' -value { if ($this.checks.Count -eq 0) { Write-IcingaPluginOutput ( [string]::Format( - '{0}{1}: No checks configured for package "{2}"', + '{0}{1} No checks configured for package "{2}"', (New-StringTree ($this.spacing + 1)), $IcingaEnums.IcingaExitCodeText.($this.exitcode), $this.name @@ -287,31 +315,37 @@ function New-IcingaCheckPackage() return; } - [string]$outputMessage = '{0}{1}: Check package "{2}" is {1}'; + [string]$outputMessage = '{0}{1} Check package "{2}"'; if ($this.verbose -ne 0) { $outputMessage += ' ({3})'; } + if ($this.exitcode -ne 0 -And $this.spacing -eq 0) { + $outputMessage += ' - {4}'; + } + Write-IcingaPluginOutput ( [string]::Format( $outputMessage, (New-StringTree $this.spacing), $IcingaEnums.IcingaExitCodeText.($this.exitcode), $this.name, - $this.GetPackageConfigMessage() + $this.GetPackageConfigMessage(), + $this.headermsg ) ); } $Check | Add-Member -membertype ScriptMethod -name 'PrintOutputMessages' -value { - [bool]$printDetails = $FALSE; [bool]$printAll = $FALSE; switch ($this.verbose) { - 0 { break; }; - 1 { break; }; - 2 { - $printDetails = $TRUE; + 0 { + # Default value. Only print a package but not the services include + break; + }; + 1 { + # Include the Operator into the check package result break; }; Default { @@ -325,8 +359,7 @@ function New-IcingaCheckPackage() if ($printAll) { $this.WriteAllOutput(); $this.PrintNoChecksConfigured(); - } elseif ($printDetails) { - # Now print Non-Ok Check outputs in case our package is not Ok + } else { if ([int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { $this.WriteCheckErrors(); $this.PrintNoChecksConfigured(); @@ -334,15 +367,57 @@ function New-IcingaCheckPackage() } } + $Check | Add-Member -membertype ScriptMethod -name 'AddUniqueSortedChecksToHeader' -value { + param($checkarray, $state); + + [hashtable]$CheckHash = @{}; + + foreach ($entry in $checkarray) { + if ($CheckHash.ContainsKey($entry) -eq $FALSE) { + $CheckHash.Add($entry, $TRUE); + } + } + + [array]$SortedCheckArray = $CheckHash.GetEnumerator() | Sort-Object name; + + if ($SortedCheckArray.Count -ne 0) { + $this.headermsg += [string]::Format( + '{0} {1} ', + $IcingaEnums.IcingaExitCodeText[$state], + [string]::Join(', ', $SortedCheckArray.Key) + ); + } + } + $Check | Add-Member -membertype ScriptMethod -name 'GetWorstExitCode' -value { if ([int]$this.exitcode -eq [int]$IcingaEnums.IcingaExitCode.Unknown) { return; } + foreach ($check in $this.checks) { if ([int]$this.exitcode -lt $check.exitcode) { $this.exitcode = $check.exitcode; } + + $this.criticalchecks += $check.GetCriticals(); + $this.warningchecks += $check.GetWarnings(); + $this.unknownchecks += $check.GetUnknowns(); } + + # Only apply this to our top package + if ($this.spacing -ne 0) { + return; + } + + $this.AddUniqueSortedChecksToHeader( + $this.criticalchecks, $IcingaEnums.IcingaExitCode.Critical + ); + $this.AddUniqueSortedChecksToHeader( + $this.warningchecks, $IcingaEnums.IcingaExitCode.Warning + ); + $this.AddUniqueSortedChecksToHeader( + $this.unknownchecks, $IcingaEnums.IcingaExitCode.Unknown + ); } $Check | Add-Member -membertype ScriptMethod -name 'GetPerfData' -value {