lib/core/perfcounter/New-IcingaPerformanceCounterArray.psm1
<# .SYNOPSIS Accepts a list of Performance Counters which will all be fetched at once and returned as a hashtable object. No additional configuration is required. .DESCRIPTION Accepts a list of Performance Counters which will all be fetched at once and returned as a hashtable object. No additional configuration is required. .FUNCTIONALITY Accepts a list of Performance Counters which will all be fetched at once and returned as a hashtable object. No additional configuration is required. .EXAMPLE PS>New-IcingaPerformanceCounterArray -CounterArray '\Processor(*)\% processor time', '\Memory\committed bytes'; Name Value ---- ----- \Processor(*)\% processor time {\Processor(7)\% processor time, \Processor(6)\% processor time, \Processor(0)\% proc... \Memory\committed bytes {error, sample, type, value...} .PARAMETER CounterArray An array of Performance Counters which will all be fetched at once .INPUTS System.String .OUTPUTS System.Hashtable .LINK https://github.com/Icinga/icinga-powershell-framework #> function New-IcingaPerformanceCounterArray() { param( [array]$CounterArray = @() ) [hashtable]$CounterResult = @{}; [bool]$RequireSleep = $TRUE; foreach ($counter in $CounterArray) { # We want to speed up things with loading, so we will check if a specified # Counter is already cached within our hashtable. If it is not, we sleep # at the end of the function the required 500ms and don't have to wait # NumOfCounters * 500 milliseconds for the first runs. This will speed # up the general loading of counters and will not require some fancy # pre-caching / configuration handler $CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter; if ($null -ne $CachedCounter) { $RequireSleep = $FALSE; } $obj = New-IcingaPerformanceCounter -Counter $counter -SkipWait $TRUE; if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) { $CounterResult.Add($obj.Name(), $obj.Value()); } } # 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: # New-IcingaPerformanceCounterCache $CounterResult; # Internally we could do something like this # $global:Icinga_PerfCounterCache += $CounterResult; # Above we initialse ever single counter and we only require a sleep once # in case a new, yet unknown counter was added if ($RequireSleep) { Start-Sleep -Milliseconds 500; # Agreed, this is some sort of code duplication but it wouldn't make # any sense to create a own function for this. Why are we doing # this anway? # Simple: In case we found counters which have yet not been initialised # we did this above. Now we have waited 500 ms to receive proper # values from these counters. As the previous generated result # might have contained counters with 0 results, we will now # check all counters again to receive the proper values. # Agreed, might sound like a overhead, but the impact only # applies to the first call of the module with the counters. # This 'duplication' however decreased the execution from # certain modules from 25s to 1s on the first run. Every # additional run is then beeing executed within 0.x s # which sounds like a very good performance and solution $CounterResult = @{}; foreach ($counter in $CounterArray) { $obj = New-IcingaPerformanceCounter -Counter $counter -SkipWait $TRUE; if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) { $CounterResult.Add($obj.Name(), $obj.Value()); } } } return $CounterResult; } |