Merge pull request #799 from Icinga:fix/icinga_check_value_conversion_incorrect

Fix: Wrong performance data values on unit conversion

Fixes an issue with the new check handling, which did not properly convert values from checks to the correct performance data values and base values in some cases
This commit is contained in:
Lord Hepipud 2025-04-22 09:46:49 +02:00 committed by GitHub
commit f2f935ff90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 130 additions and 17 deletions

View file

@ -11,9 +11,14 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
[Issues and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/38)
## 1.13.3 (tbd)
[Issues and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/39)
### Bugfixes
* [#787](https://github.com/Icinga/icinga-powershell-framework/pull/787) Fixes the return value in case the `Agent` component could not be installed from `$FALSE` to `null`
* [#796](https://github.com/Icinga/icinga-powershell-framework/issues/796) [#798](https://github.com/Icinga/icinga-powershell-framework/issues/798) Fixes an issue with the new check handling, which did not properly convert values from checks to the correct performance data values and base values in some cases
## 1.13.3 (tbd)

View file

@ -0,0 +1,38 @@
<#
.SYNOPSIS
Converts a time string to a Unix timestamp.
.DESCRIPTION
Converts a given time string like "2025-04-10 20:00:00" to a Unix timestamp.
The function returns 0 if the input is null or empty.
If the input cannot be parsed, it returns -1.
The function uses the UTC time zone for the conversion.
.PARAMETER TimeString
The time string to convert. It should be in a format that can be parsed by [datetime]::Parse, like "2025-04-10 20:00:00"
.EXAMPLE
$UnixTime = ConvertTo-IcingaUnixTime -TimeString "2025-04-10 20:00:00"
$UnixTime
#>
function ConvertTo-IcingaUnixTime()
{
param (
[string]$TimeString = $null
);
if ([string]::IsNullOrEmpty($TimeString)) {
return 0;
}
try {
return [decimal][double]::Parse(
(Get-Date -UFormat %s -Date (Get-Date -Date $TimeString).ToUniversalTime())
);
} catch {
return -1;
}
return 0;
}

View file

@ -0,0 +1,51 @@
<#
.SYNOPSIS
Calculates the offset in seconds between the current Unix time and a specified Unix time or time string.
.DESCRIPTION
The `Get-IcingaUnixTimeOffsetNow` function computes the difference in seconds between the current Unix time and a provided Unix time or time string. If no valid input is provided, the function returns 0.
.PARAMETER TimeString
A string representing a specific time. This string will be converted to Unix time using the `ConvertTo-IcingaUnixTime` function.
.PARAMETER UnixTime
A decimal value representing a specific Unix time. If provided, the offset will be calculated using this value.
.RETURNS
The offset in seconds as a decimal value. If no valid input is provided or the conversion fails, the function returns 0.
.EXAMPLE
PS> Get-IcingaUnixTimeOffsetNow -TimeString "2025-04-20 10:00:00"
Calculates the offset in seconds between the current Unix time and the specified time string.
.EXAMPLE
PS> Get-IcingaUnixTimeOffsetNow -UnixTime 1672531200
Calculates the offset in seconds between the current Unix time and the specified Unix time.
.NOTES
This function depends on the `ConvertTo-IcingaUnixTime` and `Get-IcingaUnixTime` functions to perform time conversions and retrieve the current Unix time.
#>
function Get-IcingaUnixTimeOffsetNow()
{
param (
[string]$TimeString = '',
[decimal]$UnixTime = 0
);
if ([string]::IsNullOrEmpty($TimeString) -And $UnixTime -eq 0) {
return 0;
}
if ([string]::IsNullOrEmpty($TimeString) -eq $FALSE) {
$UnixTime = ConvertTo-IcingaUnixTime -TimeString $TimeString;
if ($UnixTime -le 0) {
return 0;
}
}
$CurrentUnixTime = Get-IcingaUnixTime;
return ($CurrentUnixTime - $UnixTime);
}

View file

@ -134,6 +134,24 @@ function Compare-IcingaPluginThresholds()
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'Minimum' -Value (Convert-IcingaPluginThresholds -Threshold $Minium);
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'Maximum' -Value (Convert-IcingaPluginThresholds -Threshold $Maximum);
if ($TestInput.Decimal) {
$ConvertedValue = Convert-IcingaPluginThresholds -Threshold ([string]::Format('{0}{1}', $InputValue, $Unit));
if ((Test-IcingaDecimal -Value $ConvertedValue.Value).Decimal) {
$InputValue = [decimal]$ConvertedValue.Value;
$IcingaThresholds.Value = [decimal]$ConvertedValue.Value;
$IcingaThresholds.Unit = $ConvertedValue.Unit;
}
}
if ($BaseInput.Decimal) {
$ConvertedBaseValue = Convert-IcingaPluginThresholds -Threshold ([string]::Format('{0}{1}', $BaseValue, $Unit));
if ((Test-IcingaDecimal -Value $ConvertedBaseValue.Value).Decimal) {
$BaseValue = [decimal]$ConvertedBaseValue.Value;
}
}
# In case we are using % values, we should set the BaseValue always to 100
if ($Unit -eq '%' -And $null -eq $BaseValue) {
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'BaseValue' -Value 100;
@ -144,17 +162,17 @@ function Compare-IcingaPluginThresholds()
$CheckResult = $null;
if ($Matches) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Matches -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Matches -MetricsOverTime $MoTData;
} elseif ($NotMatches) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.NotMatches -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.NotMatches -MetricsOverTime $MoTData;
} elseif ($IsBetween) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Between -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Between -MetricsOverTime $MoTData;
} elseif ($IsLowerEqual) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.LowerEqual -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.LowerEqual -MetricsOverTime $MoTData;
} elseif ($IsGreaterEqual) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.GreaterEqual -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.GreaterEqual -MetricsOverTime $MoTData;
} else {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -MetricsOverTime $MoTData;
}
$IcingaThresholds.Message = $CheckResult.Message;

View file

@ -57,6 +57,7 @@ function Compare-IcingaPluginValueToThreshold()
$Value = $null,
$BaseValue = $null,
$Unit = $null,
$CheckUnit = $null,
$Translation = $null,
$Threshold = $null,
$OverrideMode = $null,
@ -94,7 +95,7 @@ function Compare-IcingaPluginValueToThreshold()
# Otherwise just convert the values to human readble values
$HumanReadableValue = ConvertTo-IcingaPluginOutputTranslation -Translation $Translation -Value $HumanReadableValue;
$HumanReadableValue = Convert-IcingaPluginValueToString -Value $HumanReadableValue -Unit $Unit;
$HumanReadableValue = Convert-IcingaPluginValueToString -Value $HumanReadableValue -Unit $Unit -OriginalUnit $CheckUnit;
if ($null -eq $Value -Or $null -eq $Threshold -Or [string]::IsNullOrEmpty($Threshold.Raw)) {
$RetValue.Message = $HumanReadableValue;
@ -139,7 +140,7 @@ function Compare-IcingaPluginValueToThreshold()
}
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
}
@ -147,42 +148,42 @@ function Compare-IcingaPluginValueToThreshold()
};
$IcingaEnums.IcingaThresholdMethod.Lower {
if ($Value -lt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is lower than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is lower than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.LowerEqual {
if ($Value -le $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is lower or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is lower or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Greater {
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.GreaterEqual {
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Between {
if ($Value -lt $Threshold.StartRange -Or $Value -gt $Threshold.EndRange) {
$RetValue.Message = [string]::Format('Value {0} is not between thresholds <{1} or >{2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is not between thresholds <{1} or >{2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Outside {
if ($Value -ge $Threshold.StartRange -And $Value -le $Threshold.EndRange) {
$RetValue.Message = [string]::Format('Value {0} is between thresholds >={1} and <={2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is between thresholds >={1} and <={2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;

View file

@ -258,9 +258,9 @@ function New-IcingaCheck()
[string]$PerfDataLabel = [string]::Format(
'{0}={1}{2};{3};{4};{5};{6}',
$PerfDataName,
$PerfDataName.ToLower(),
(Format-IcingaPerfDataValue $value),
$this.__ThresholdObject.PerfUnit,
$this.__ThresholdObject.Unit,
(Format-IcingaPerfDataValue $warning),
(Format-IcingaPerfDataValue $critical),
(Format-IcingaPerfDataValue $this.Minimum),
@ -289,7 +289,7 @@ function New-IcingaCheck()
}
}
$Global:Icinga.Private.Scheduler.PerfDataWriter.Storage.Append($PerfDataLabel.ToLower()) | Out-Null;
$Global:Icinga.Private.Scheduler.PerfDataWriter.Storage.Append($PerfDataLabel) | Out-Null;
}
$IcingaCheck | Add-Member -MemberType ScriptMethod -Name '__ValidateObject' -Value {