mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2026-02-03 04:09:29 -05:00
Merge pull request #828 from Icinga:feature/adds_cache_update_for_performance_counters
Feature: Adds caching update for added/removed performance counter instances Adds feature to update the cache for performance counter instances to keep track of system changes. This will ensure that while we are running as a daemon with Icinga for Windows, newly added or removed information for performance counters will be updated whenever required.
This commit is contained in:
commit
ad59bb9a3a
5 changed files with 109 additions and 25 deletions
|
|
@ -20,6 +20,7 @@ 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
|
* [#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
|
||||||
|
|
||||||
## 1.13.4 (tbd)
|
## 1.13.4 (tbd)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@
|
||||||
if multiple counters are fetched during one call with this function if the sleep
|
if multiple counters are fetched during one call with this function if the sleep
|
||||||
is done afterwards manually. A sleep is set to 500ms to ensure counter data is
|
is done afterwards manually. A sleep is set to 500ms to ensure counter data is
|
||||||
valid and contains an offset from previous/current values
|
valid and contains an offset from previous/current values
|
||||||
|
.PARAMETER NoCache
|
||||||
|
Set this if no caching of the counter is intended. This will prevent from adding
|
||||||
|
single counters to the internal cache during update phase
|
||||||
.INPUTS
|
.INPUTS
|
||||||
System.String
|
System.String
|
||||||
.LINK
|
.LINK
|
||||||
|
|
@ -36,7 +39,8 @@ function New-IcingaPerformanceCounter()
|
||||||
{
|
{
|
||||||
param(
|
param(
|
||||||
[string]$Counter = '',
|
[string]$Counter = '',
|
||||||
[boolean]$SkipWait = $FALSE
|
[boolean]$SkipWait = $FALSE,
|
||||||
|
[switch]$NoCache = $FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
# Simply use the counter name, like
|
# Simply use the counter name, like
|
||||||
|
|
@ -45,7 +49,7 @@ function New-IcingaPerformanceCounter()
|
||||||
return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage 'Failed to initialise counter, as no counter was specified.');
|
return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage 'Failed to initialise counter, as no counter was specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
[array]$CounterArray = $Counter.Split('\');
|
[array]$CounterArray = $Counter.Split('\');
|
||||||
[string]$UseCounterCategory = '';
|
[string]$UseCounterCategory = '';
|
||||||
[string]$UseCounterName = '';
|
[string]$UseCounterName = '';
|
||||||
[string]$UseCounterInstance = '';
|
[string]$UseCounterInstance = '';
|
||||||
|
|
@ -72,6 +76,13 @@ function New-IcingaPerformanceCounter()
|
||||||
# At last get the actual counter containing our values
|
# At last get the actual counter containing our values
|
||||||
$UseCounterName = $CounterArray[2];
|
$UseCounterName = $CounterArray[2];
|
||||||
|
|
||||||
|
if ($NoCache -eq $FALSE) {
|
||||||
|
# If we are not skipping the cache, we will update the cache
|
||||||
|
# with the current counter path. This will ensure that we
|
||||||
|
# have a valid cache for the counter and can return it later
|
||||||
|
Update-IcingaPerformanceCounterCache -Counter $Counter;
|
||||||
|
}
|
||||||
|
|
||||||
# Now as we know how the counter path is constructed and has been split into
|
# Now as we know how the counter path is constructed and has been split into
|
||||||
# the different values, we need to know how to handle the instances of the counter
|
# the different values, we need to know how to handle the instances of the counter
|
||||||
|
|
||||||
|
|
@ -80,11 +91,13 @@ function New-IcingaPerformanceCounter()
|
||||||
# which contains the parent name including counters for all instances that
|
# which contains the parent name including counters for all instances that
|
||||||
# have been found
|
# have been found
|
||||||
if ($UseCounterInstance -eq '*') {
|
if ($UseCounterInstance -eq '*') {
|
||||||
# In case we already loaded the counters once, return the finished array
|
if ($NoCache -eq $FALSE) {
|
||||||
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter;
|
# In case we already loaded the counters once, return the finished array
|
||||||
|
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter;
|
||||||
|
|
||||||
if ($null -ne $CachedCounter) {
|
if ($null -ne $CachedCounter) {
|
||||||
return (New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $CachedCounter);
|
return (New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $CachedCounter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# If we need to build the array, load all instances from the counters and
|
# If we need to build the array, load all instances from the counters and
|
||||||
|
|
@ -116,7 +129,9 @@ function New-IcingaPerformanceCounter()
|
||||||
# Add the parent counter including the array of Performance Counters to our
|
# Add the parent counter including the array of Performance Counters to our
|
||||||
# caching mechanism and return the New-IcingaPerformanceCounterResult object for usage
|
# caching mechanism and return the New-IcingaPerformanceCounterResult object for usage
|
||||||
# within the monitoring modules
|
# within the monitoring modules
|
||||||
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $AllCountersInstances;
|
if ($NoCache -eq $FALSE) {
|
||||||
|
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $AllCountersInstances;
|
||||||
|
}
|
||||||
return (New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $AllCountersInstances);
|
return (New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $AllCountersInstances);
|
||||||
} else {
|
} else {
|
||||||
# This part will handle the counters without any instances as well as
|
# This part will handle the counters without any instances as well as
|
||||||
|
|
@ -124,16 +139,22 @@ function New-IcingaPerformanceCounter()
|
||||||
|
|
||||||
# In case we already have the counter within our cache, return the
|
# In case we already have the counter within our cache, return the
|
||||||
# cached informations
|
# cached informations
|
||||||
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter;
|
if ($NoCache -eq $FALSE) {
|
||||||
|
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter;
|
||||||
|
|
||||||
if ($null -ne $CachedCounter) {
|
if ($null -ne $CachedCounter) {
|
||||||
return $CachedCounter;
|
return $CachedCounter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the cache is not present yet, create the Performance Counter object,
|
# If the cache is not present yet, create the Performance Counter object,
|
||||||
# and add it to our cache
|
# and add it to our cache
|
||||||
$NewCounter = New-IcingaPerformanceCounterObject -FullName $Counter -Category $UseCounterCategory -Counter $UseCounterName -Instance $UseCounterInstance -SkipWait $SkipWait;
|
$NewCounter = New-IcingaPerformanceCounterObject -FullName $Counter -Category $UseCounterCategory -Counter $UseCounterName -Instance $UseCounterInstance -SkipWait $SkipWait;
|
||||||
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $NewCounter;
|
if ($NoCache -eq $FALSE) {
|
||||||
|
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $NewCounter;
|
||||||
|
} else {
|
||||||
|
return $NewCounter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function will always return non-instance counters or
|
# This function will always return non-instance counters or
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,6 @@ function New-IcingaPerformanceCounterArray()
|
||||||
# NumOfCounters * 500 milliseconds for the first runs. This will speed
|
# NumOfCounters * 500 milliseconds for the first runs. This will speed
|
||||||
# up the general loading of counters and will not require some fancy
|
# up the general loading of counters and will not require some fancy
|
||||||
# pre-caching / configuration handler
|
# pre-caching / configuration handler
|
||||||
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter;
|
|
||||||
|
|
||||||
# Remove this for now to ensure our CPU metrics will not be cached
|
|
||||||
# and represent correct values, not exceeding 200% and beyond
|
|
||||||
#if ($null -ne $CachedCounter) {
|
|
||||||
# $RequireSleep = $FALSE;
|
|
||||||
#}
|
|
||||||
|
|
||||||
$obj = New-IcingaPerformanceCounter -Counter $counter -SkipWait $TRUE;
|
$obj = New-IcingaPerformanceCounter -Counter $counter -SkipWait $TRUE;
|
||||||
if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) {
|
if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) {
|
||||||
|
|
@ -54,12 +47,6 @@ function New-IcingaPerformanceCounterArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: Add a cache for our Performance Counters to only fetch them once
|
|
||||||
# for each session to speed up the loading. This cold be something like
|
|
||||||
# this:
|
|
||||||
#
|
|
||||||
# $Global:Icinga.Private.PerformanceCounter.Cache += $CounterResult;
|
|
||||||
|
|
||||||
# Above we initialise ever single counter and we only require a sleep once
|
# Above we initialise ever single counter and we only require a sleep once
|
||||||
# in case a new, yet unknown counter was added
|
# in case a new, yet unknown counter was added
|
||||||
if ($RequireSleep) {
|
if ($RequireSleep) {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ function Show-IcingaPerformanceCounterInstances()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$PerfCounter = New-IcingaPerformanceCounter -Counter $Counter -SkipWait $TRUE;
|
$PerfCounter = New-IcingaPerformanceCounter -Counter $Counter -SkipWait $TRUE -NoCache;
|
||||||
|
|
||||||
foreach ($entry in $PerfCounter.Counters) {
|
foreach ($entry in $PerfCounter.Counters) {
|
||||||
$Instances.Add(
|
$Instances.Add(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Updates the cached instances of a specified performance counter in the Icinga PowerShell Framework.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
The Update-IcingaPerformanceCounterCache function synchronizes the cached instances of a given performance counter.
|
||||||
|
It removes instances that no longer exist and adds new instances that are not yet cached.
|
||||||
|
This ensures that the cache accurately reflects the current state of the performance counter instances.
|
||||||
|
|
||||||
|
.PARAMETER Counter
|
||||||
|
The name of the performance counter whose cache should be updated.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Update-IcingaPerformanceCounterCache -Counter "\Processor(_Total)\% Processor Time"
|
||||||
|
|
||||||
|
Updates the cache for the specified performance counter.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
This function is intended for internal use within the Icinga PowerShell Framework.
|
||||||
|
It requires that the global cache variable and related functions are available.
|
||||||
|
|
||||||
|
#>
|
||||||
|
function Update-IcingaPerformanceCounterCache()
|
||||||
|
{
|
||||||
|
param (
|
||||||
|
$Counter
|
||||||
|
);
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($Counter)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Global:Icinga.Private.PerformanceCounter.Cache.ContainsKey($Counter) -eq $FALSE) {
|
||||||
|
# If there is no cache entry for the provided counter, we don't need to do anything yet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# First we need to prepare some data by fetching the current instances of the counter
|
||||||
|
# and the cached instances. We will then compare them and update the cache accordingly
|
||||||
|
[array]$CounterInstances = Show-IcingaPerformanceCounterInstances -Counter $Counter;
|
||||||
|
[array]$CachedInstances = $Global:Icinga.Private.PerformanceCounter.Cache[$Counter];
|
||||||
|
[array]$UpdatedInstances = @();
|
||||||
|
[array]$CachedInstanceNames = $CachedInstances.FullName;
|
||||||
|
|
||||||
|
# We will now iterate over the cached instances and check if they are still present in the current
|
||||||
|
# counter instances. If they are not, we will remove them from the cache.
|
||||||
|
# If they are present, we will keep them in the updated instances array.
|
||||||
|
for ($index = 0; $index -lt $CachedInstances.Count; $index++) {
|
||||||
|
$cachedInstance = $CachedInstances[$index];
|
||||||
|
$instanceName = $cachedInstance.FullName;
|
||||||
|
|
||||||
|
# If the instance is not in the current list, we remove it
|
||||||
|
if ($CounterInstances.Value -contains $instanceName) {
|
||||||
|
$UpdatedInstances += $cachedInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now we will iterate over the current counter instances and check if they are already cached.
|
||||||
|
# If they are not, we will add them to the updated instances array.
|
||||||
|
# This ensures that we only add new instances that are not already cached.
|
||||||
|
for ($index = 0; $index -lt $CounterInstances.Count; $index++) {
|
||||||
|
$instanceName = $CounterInstances[$index].Value;
|
||||||
|
|
||||||
|
if ($CachedInstanceNames -notcontains $instanceName) {
|
||||||
|
# If the instance is not cached, we create a new performance counter object
|
||||||
|
# and add it to the updated instances array
|
||||||
|
$UpdatedInstances += (New-IcingaPerformanceCounter -Counter $instanceName -SkipWait $TRUE -NoCache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Finally, we update the cache with the new instances
|
||||||
|
# This will ensure that the cache is up-to-date with the current state of the performance
|
||||||
|
# counter instances
|
||||||
|
$Global:Icinga.Private.PerformanceCounter.Cache[$Counter] = $UpdatedInstances;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue