mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2026-02-03 12:19:29 -05:00
This adds new and improved handling for Metrics over Time. The overall execution time for the background tasks has been reduced, while also the memory management is way more efficient. In addition to the improved core handling of the feature, performance metrics for metrics over time will NO LONGER BE WRITTEN. This will increase the performance of the graphing solutions like InfluxDB a lot, while the monitoring by using the "-ThresholdInterval" argument is still possible. ```powershell PS> Invoke-IcingaCheckCPU -Warning '5%' -ThresholdInterval '10m'; [WARNING] CPU Load [WARNING] Overall Load, Socket #0 \_ [WARNING] Overall Load: Value 6.546175% is greater than threshold 5% (10m Avg.) \_ [WARNING] Socket #0 \_ [WARNING] Core 0: Value 18.391566% is greater than threshold 5% (10m Avg.) \_ [WARNING] Core 1: Value 14.100505% is greater than threshold 5% (10m Avg.) \_ [WARNING] Core Total: Value 6.546175% is greater than threshold 5% (10m Avg.) | totalload::ifw_cpu::load=5.804053;5;;0;100 0_0::ifw_cpu::load=18.03764;5;;0;100 0_1::ifw_cpu::load=9.36611;5;;0;100 0_2::ifw_cpu::load=5.830669;5;;0;100 0_3::ifw_cpu::load=0.646737;5;;0;100 0_4::ifw_cpu::load=0.926955;5;;0;100 0_5::ifw_cpu::load=0.016205;5;;0;100 0_total::ifw_cpu::load=5.804053;5;;0;100 ```
133 lines
6.5 KiB
PowerShell
133 lines
6.5 KiB
PowerShell
function Add-IcingaServiceCheckTask()
|
|
{
|
|
param (
|
|
$CheckCommand,
|
|
$Arguments,
|
|
$Interval,
|
|
$TimeIndexes,
|
|
$CheckId
|
|
);
|
|
|
|
# $Global:Icinga.Private.Daemons.ServiceCheck
|
|
New-IcingaServiceCheckDaemonEnvironment `
|
|
-CheckCommand $CheckCommand `
|
|
-Arguments $Arguments `
|
|
-TimeIndexes $TimeIndexes;
|
|
|
|
# Read our check result store data from disk for this service check
|
|
Read-IcingaCheckResultStore -CheckCommand $CheckCommand;
|
|
|
|
$MetricCacheFile = Join-Path -Path (Join-Path -Path (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'service_check_cache') -ChildPath 'metrics') -ChildPath ([string]::Format('{0}.xml', $CheckCommand));
|
|
[int]$CheckInterval = ConvertTo-Seconds $Interval;
|
|
[hashtable]$CheckDataCache = @{ };
|
|
[array]$PerfDataEntries = @();
|
|
|
|
if (Test-Path -Path $MetricCacheFile) {
|
|
$CheckDataCache = [System.Management.Automation.PSSerializer]::Deserialize((Get-Content -Path $MetricCacheFile -Raw -Encoding UTF8));
|
|
}
|
|
|
|
while ($TRUE) {
|
|
if ($Global:Icinga.Private.Daemons.ServiceCheck.PassedTime -lt $CheckInterval) {
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.PassedTime += 1;
|
|
Start-Sleep -Seconds 1;
|
|
|
|
continue;
|
|
}
|
|
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.PassedTime = 0;
|
|
|
|
# Clear possible previous performance data from the daemon cache
|
|
$Global:Icinga.Private.Scheduler.PerfDataWriter.Daemon.Clear();
|
|
|
|
# Execute our check with possible arguments
|
|
try {
|
|
& $CheckCommand @Arguments | Out-Null;
|
|
} catch {
|
|
Write-IcingaEventMessage -EventId 1451 -Namespace 'Framework' -ExceptionObject $_ -Objects $CheckCommand, ($Arguments | Out-String), (Get-IcingaInternalPluginOutput);
|
|
|
|
Clear-IcingaCheckSchedulerEnvironment;
|
|
|
|
# Force Icinga for Windows Garbage Collection
|
|
Optimize-IcingaForWindowsMemory -ClearErrorStack -SmartGC;
|
|
|
|
continue;
|
|
}
|
|
|
|
$UnixTime = Get-IcingaUnixTime;
|
|
|
|
foreach ($PerfLabel in $Global:Icinga.Private.Scheduler.PerfDataWriter.Daemon.Keys) {
|
|
$PerfValue = $Global:Icinga.Private.Scheduler.PerfDataWriter.Daemon[$PerfLabel].Value;
|
|
$PerfUnit = $Global:Icinga.Private.Scheduler.PerfDataWriter.Daemon[$PerfLabel].Unit;
|
|
|
|
if ($CheckDataCache.ContainsKey($PerfLabel) -eq $FALSE) {
|
|
$CheckDataCache.Add($PerfLabel, (New-Object System.Collections.ArrayList));
|
|
}
|
|
|
|
$CheckDataCache[$PerfLabel].Add(
|
|
@{
|
|
'Time' = $UnixTime;
|
|
'Value' = $PerfValue;
|
|
'Unit' = $PerfUnit;
|
|
}
|
|
) | Out-Null;
|
|
|
|
[int]$IndexCount = $CheckDataCache[$PerfLabel].Count;
|
|
[int]$RemoveIndex = 0;
|
|
for ($i = 0; $i -lt $IndexCount; $i++) {
|
|
# In case we store more values than we require for our max time range, remove the oldest one
|
|
if (($UnixTime - $Global:Icinga.Private.Daemons.ServiceCheck.MaxTimeInSeconds) -gt [int]($CheckDataCache[$PerfLabel][$i].Time)) {
|
|
$RemoveIndex += 1;
|
|
continue;
|
|
}
|
|
|
|
# Calculate the average value for our performance data based on the remaining data
|
|
foreach ($calc in $Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation.Keys) {
|
|
if (($UnixTime - $Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Time) -le [int]($CheckDataCache[$PerfLabel][$i].Time)) {
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Sum += $CheckDataCache[$PerfLabel][$i].Value;
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Count += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Remove older entries more efficiently. As we store the data in an ArrayList, the oldest entries are at the beginning
|
|
# Therefore we can just remove a range of entries from the beginning of the list or clear the list if we need to remove all entries
|
|
if ($RemoveIndex -gt 0) {
|
|
if ($RemoveIndex -ge $IndexCount) {
|
|
$CheckDataCache[$PerfLabel].Clear() | Out-Null;
|
|
} else {
|
|
$CheckDataCache[$PerfLabel].RemoveRange(0, $RemoveIndex) | Out-Null;
|
|
}
|
|
$RemoveIndex = 0;
|
|
}
|
|
|
|
# Now calculate the average values for our performance data
|
|
foreach ($calc in $Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation.Keys) {
|
|
if ($Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Count -ne 0) {
|
|
$AverageValue = ($Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Sum / $Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Count);
|
|
[string]$MetricMultiName = [string]::Format('{0}::Interval{1}={2}{3}', $PerfLabel, $Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Time, (Format-IcingaPerfDataValue $AverageValue), $PerfUnit);
|
|
# Write our performance data label
|
|
$PerfDataEntries += $MetricMultiName;
|
|
}
|
|
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Sum = 0;
|
|
$Global:Icinga.Private.Daemons.ServiceCheck.AverageCalculation[$calc].Count = 0;
|
|
}
|
|
}
|
|
|
|
$Global:Icinga.Public.Daemons.ServiceCheck.PerformanceDataCache[$CheckCommand] = $PerfDataEntries -Join ' ';
|
|
$PerfDataEntries = @();
|
|
|
|
$PerformanceLabelFile = Join-Path -Path (Join-Path -Path (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'service_check_cache') -ChildPath 'performance_labels') -ChildPath ([string]::Format('{0}.db', $CheckCommand));
|
|
$CheckCacheXMLObj = [System.Management.Automation.PSSerializer]::Serialize($CheckDataCache);
|
|
|
|
if ((Test-Path -Path $PerformanceLabelFile) -eq $FALSE) {
|
|
New-Item -Path $PerformanceLabelFile -ItemType File -Force | Out-Null;
|
|
}
|
|
if ((Test-Path -Path $MetricCacheFile) -eq $FALSE) {
|
|
New-Item -Path $MetricCacheFile -ItemType File -Force | Out-Null;
|
|
}
|
|
|
|
Set-Content -Path $PerformanceLabelFile -Value $Global:Icinga.Public.Daemons.ServiceCheck.PerformanceDataCache[$CheckCommand] -Force -Encoding UTF8;
|
|
Set-Content -Path $MetricCacheFile -Value $CheckCacheXMLObj -Force -Encoding UTF8;
|
|
}
|
|
}
|