Merge pull request #107 from Icinga/feature/performance_counter_functionality

Feature: Performance Counter docs and functionality

* Adds help for each single Performance Counter Cmdlet
* Adds feature to filter for categories on `Show-IcingaPerformanceCounterCategories`
* Adds feature to test if a category exists with `Test-IcingaPerformanceCounterCategory`
* Places each Cmdlet into a single .psm1 file
This commit is contained in:
Lord Hepipud 2020-08-20 14:30:57 +02:00 committed by GitHub
commit be3a2a44c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 465 additions and 114 deletions

View file

@ -36,6 +36,7 @@ Check Command configuration generated by Icinga for Windows 1.2.0 require Icinga
* [#95](https://github.com/Icinga/icinga-powershell-framework/issues/95) Improves error handling for issues by using `Use-Icinga` initialising or by calling plugins which are not installed * [#95](https://github.com/Icinga/icinga-powershell-framework/issues/95) Improves error handling for issues by using `Use-Icinga` initialising or by calling plugins which are not installed
* [#98](https://github.com/Icinga/icinga-powershell-framework/issues/98) Adds support for SecureString as password argument on config generation * [#98](https://github.com/Icinga/icinga-powershell-framework/issues/98) Adds support for SecureString as password argument on config generation
* [#99](https://github.com/Icinga/icinga-powershell-framework/issues/99) Improves plugin output with different verbosity settings * [#99](https://github.com/Icinga/icinga-powershell-framework/issues/99) Improves plugin output with different verbosity settings
* [#100](https://github.com/Icinga/icinga-powershell-framework/issues/100), [#107](https://github.com/Icinga/icinga-powershell-framework/issues/107) Adds help for each Performance Counter Cmdlet, separates Cmdlets into single files, adds `Filter` option for `Show-IcingaPerformanceCounterCategories` and adds `Test-IcingaPerformanceCounterCategory` to test if a category exists on a system
### Bugfixes ### Bugfixes

View file

@ -0,0 +1,37 @@
<#
.SYNOPSIS
Adds counter instances or single counter objects to an internal cache
by a given counter name or full path
.DESCRIPTION
Adds counter instances or single counter objects to an internal cache
by a given counter name or full path
.FUNCTIONALITY
Adds counter instances or single counter objects to an internal cache
by a given counter name or full path
.EXAMPLE
PS>Add-IcingaPerformanceCounterCache -Counter '\Processor(*)\% processor time' -Instances $CounterInstances;
.PARAMETER Counter
The path to the counter to store data for
.PARAMETER Instances
The value to store for a specific path to a counter
.INPUTS
System.String
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Add-IcingaPerformanceCounterCache()
{
param (
$Counter,
$Instances
);
if ($global:Icinga_PerfCounterCache.ContainsKey($Counter)) {
$global:Icinga_PerfCounterCache[$Counter] = $Instances;
} else {
$global:Icinga_PerfCounterCache.Add(
$Counter, $Instances
);
}
}

View file

@ -0,0 +1,32 @@
<#
.SYNOPSIS
Fetches stored data for a given performance counter path. Returns
$null if no values are assigned
.DESCRIPTION
Fetches stored data for a given performance counter path. Returns
$null if no values are assigned
.FUNCTIONALITY
Fetches stored data for a given performance counter path. Returns
$null if no values are assigned
.EXAMPLE
PS>Get-IcingaPerformanceCounterCacheItem -Counter '\Processor(*)\% processor time';
.PARAMETER Counter
The path to the counter to fetch data for
.INPUTS
System.String
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Get-IcingaPerformanceCounterCacheItem()
{
param (
$Counter
);
if ($global:Icinga_PerfCounterCache.ContainsKey($Counter)) {
return $global:Icinga_PerfCounterCache[$Counter];
}
return $null;
}

View file

@ -1,39 +0,0 @@
function New-IcingaPerformanceCounterCache()
{
if ($null -eq $global:Icinga_PerfCounterCache) {
$global:Icinga_PerfCounterCache = (
[hashtable]::Synchronized(
@{}
)
);
}
}
function Add-IcingaPerformanceCounterCache()
{
param (
$Counter,
$Instances
);
if ($global:Icinga_PerfCounterCache.ContainsKey($Counter)) {
$global:Icinga_PerfCounterCache[$Counter] = $Instances;
} else {
$global:Icinga_PerfCounterCache.Add(
$Counter, $Instances
);
}
}
function Get-IcingaPerformanceCounterCacheItem()
{
param (
$Counter
);
if ($global:Icinga_PerfCounterCache.ContainsKey($Counter)) {
return $global:Icinga_PerfCounterCache[$Counter];
}
return $null;
}

View file

@ -1,10 +1,37 @@
<# <#
# This is the main function which is called from this script, constructing our counters .SYNOPSIS
# and loading possible sub-instances from our Performance Counter. Creates counter objects and sub-instances from a given Performance Counter
# It will return either an New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
# which both contain the same members, allowing us to dynamicly use the objects which both contain the same members, allowing for dynmically use of objects
# without having to worry about exception. .DESCRIPTION
Creates counter objects and sub-instances from a given Performance Counter
Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
which both contain the same members, allowing for dynmically use of objects
.FUNCTIONALITY
Creates counter objects and sub-instances from a given Performance Counter
Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
which both contain the same members, allowing for dynmically use of objects
.EXAMPLE
PS>New-IcingaPerformanceCounter -Counter '\Processor(*)\% processor time';
FullName Counters
-------- --------
\Processor(*)\% processor time {@{FullName=\Processor(2)\% processor time; Category=Processor; Instance=2; Counter=%...
.EXAMPLE
PS>New-IcingaPerformanceCounter -Counter '\Processor(*)\% processor time' -SkipWait;
.PARAMETER Counter
The path to the Performance Counter to fetch data for
.PARAMETER SkipWait
Set this if no sleep is intended for initialising the counter. This can be useful
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
valid and contains an offset from previous/current values
.INPUTS
System.String
.LINK
https://github.com/Icinga/icinga-powershell-framework
#> #>
function New-IcingaPerformanceCounter() function New-IcingaPerformanceCounter()
{ {
param( param(

View file

@ -1,17 +1,30 @@
<# <#
# This function will make monitoring an entire list of .SYNOPSIS
# Performance counters even more easier. We simply provide Accepts a list of Performance Counters which will all be fetched at once and
# an array of Performance Counters to this module returned as a hashtable object. No additional configuration is required.
# and we will receive a construct-save result of an .DESCRIPTION
# hashtable with all performance counters including Accepts a list of Performance Counters which will all be fetched at once and
# the corresponding values. In that case the code returned as a hashtable object. No additional configuration is required.
# size decreases for larger modules. .FUNCTIONALITY
# Example: Accepts a list of Performance Counters which will all be fetched at once and
$counter = New-IcingaPerformanceCounterArray @( returned as a hashtable object. No additional configuration is required.
'\Memory\Available Bytes', .EXAMPLE
'\Memory\% Committed Bytes In Use' 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() function New-IcingaPerformanceCounterArray()
{ {
param( param(

View file

@ -0,0 +1,23 @@
<#
.SYNOPSIS
Initialises the internal cache storage for Performance Counters
.DESCRIPTION
Initialises the internal cache storage for Performance Counters
.FUNCTIONALITY
Initialises the internal cache storage for Performance Counters
.EXAMPLE
PS>New-IcingaPerformanceCounterCache;
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function New-IcingaPerformanceCounterCache()
{
if ($null -eq $global:Icinga_PerfCounterCache) {
$global:Icinga_PerfCounterCache = (
[hashtable]::Synchronized(
@{}
)
);
}
}

View file

@ -1,10 +1,34 @@
<# <#
# If some informations are missing, it could happen that .SYNOPSIS
# we are unable to create a Performance Counter. This will create a Performance Counter object in case a counter instance
# In this case we will use this Null Object, containing does not exis, but still returning default members to allow us to smoothly
# the same member functions but allowing us to maintain execute our code
# stability without unwanted exceptions .DESCRIPTION
This will create a Performance Counter object in case a counter instance
does not exis, but still returning default members to allow us to smoothly
execute our code
.FUNCTIONALITY
This will create a Performance Counter object in case a counter instance
does not exis, but still returning default members to allow us to smoothly
execute our code
.EXAMPLE
PS>New-IcingaPerformanceCounterNullObject '\Processor(20)\%processor time' -ErrorMessage 'This counter with instance 20 does not exist';
FullName ErrorMessage
-------- ------------
\Processor(20)\%processor time This counter with instance 20 does not exist
.PARAMETER FullName
The full path/name of the Performance Counter which does not exist
.PARAMETER ErrorMessage
The error message which is included within the 'error' member of the Performance Counter
.INPUTS
System.String
.OUTPUTS
System.PSObject
.LINK
https://github.com/Icinga/icinga-powershell-framework
#> #>
function New-IcingaPerformanceCounterNullObject() function New-IcingaPerformanceCounterNullObject()
{ {
param( param(

View file

@ -1,14 +1,50 @@
<# <#
# This function will create a custom Performance Counter object with .SYNOPSIS
# already initialised counters, which can be accessed with the Creates a new Performance Counter object based on given input filters.
# following members: Returns a PSObject with custom members to access the data of the counter
# Name .DESCRIPTION
# Value Creates a new Performance Counter object based on given input filters.
# Like the New-IcingaPerformanceCounterResult, this will allow to fetch the Returns a PSObject with custom members to access the data of the counter
# current values of a single counter instance including the name .FUNCTIONALITY
# of the counter. Within the New-IcingaPerformanceCounterResult function, Creates a new Performance Counter object based on given input filters.
# objects created by this function are used. Returns a PSObject with custom members to access the data of the counter
.EXAMPLE
PS>New-IcingaPerformanceCounterObject -FullName '\Processor(*)\% processor time' -Category 'Processor' -Instance '*' -Counter '% processor time';
Category : Processor
Instance : *
Counter : % processor time
PerfCounter : System.Diagnostics.PerformanceCounter
SkipWait : False
.EXAMPLE
PS>New-IcingaPerformanceCounterObject -FullName '\Processor(*)\% processor time' -Category 'Processor' -Instance '*' -Counter '% processor time' -SkipWait;
Category : Processor
Instance : *
Counter : % processor time
PerfCounter : System.Diagnostics.PerformanceCounter
SkipWait : True
.PARAMETER FullName
The full path to the Performance Counter
.PARAMETER Category
The name of the category of the Performance Counter
.PARAMETER Instance
The instance of the Performance Counter
.PARAMETER Counter
The actual name of the counter to fetch
.PARAMETER SkipWait
Set this if no sleep is intended for initialising the counter. This can be useful
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
valid and contains an offset from previous/current values
.INPUTS
System.String
.OUTPUTS
System.PSObject
.LINK
https://github.com/Icinga/icinga-powershell-framework
#> #>
function New-IcingaPerformanceCounterObject() function New-IcingaPerformanceCounterObject()
{ {
param( param(

View file

@ -1,14 +1,33 @@
<# <#
# This function will provide a virtual object, containing an array .SYNOPSIS
# of Performance Counters. The object has the following members: Will provide a virtual object, containing an array of Performance Counters.
# Name The object has the following members:
# Value * Name
# This will ensure we will not have to worry about looping an array * Value
# of mutltiple instances within a counter handler, because this .DESCRIPTION
# function will deal with everything, returning an hashtable Will provide a virtual object, containing an array of Performance Counters.
# containing the parent counter name including the values and The object has the following members:
# samples for every single instance * Name
* Value
.FUNCTIONALITY
Will provide a virtual object, containing an array of Performance Counters.
The object has the following members:
* Name
* Value
.EXAMPLE
PS>New-IcingaPerformanceCounterResult -FullName '\Processor(*)\% processor time' -PerformanceCounters $PerformanceCounters;
.PARAMETER FullName
The full path to the Performance Counter
.PARAMETER PerformanceCounters
A list of all instances/counters for the given Performance Counter
.INPUTS
System.String
.OUTPUTS
System.PSObject
.LINK
https://github.com/Icinga/icinga-powershell-framework
#> #>
function New-IcingaPerformanceCounterResult() function New-IcingaPerformanceCounterResult()
{ {
param( param(

View file

@ -1,11 +1,61 @@
# <#
# This function will get handy in case we want to fetch Counters .SYNOPSIS
# which have instances which might be helpful to group by their Will use an array of provided Performance Counter and sort the input by
# instances name. This will apply to Disk and Network Interface a given counter category. In this case we can fetch all Processor instances
# outputs for example, as it would be helpful to combine all and receive values for each core which can then be accessed from a hashtable
# counter results for a specific disk / interface in one with an eady query. Allows to modify output in addition
# result for easier working with these informations .DESCRIPTION
# Will use an array of provided Performance Counter and sort the input by
a given counter category. In this case we can fetch all Processor instances
and receive values for each core which can then be accessed from a hashtable
with an eady query. Allows to modify output in addition
.FUNCTIONALITY
Will use an array of provided Performance Counter and sort the input by
a given counter category. In this case we can fetch all Processor instances
and receive values for each core which can then be accessed from a hashtable
with an eady query. Allows to modify output in addition
.EXAMPLE
PS>New-IcingaPerformanceCounterStructure -CounterCategory 'Processor' -PerformanceCounterHash (New-IcingaPerformanceCounterArray '\Processor(*)\% processor time');
Name Value
---- -----
7 {% processor time}
3 {% processor time}
4 {% processor time}
_Total {% processor time}
2 {% processor time}
1 {% processor time}
0 {% processor time}
6 {% processor time}
5 {% processor time}
.EXAMPLE
PS>New-IcingaPerformanceCounterStructure -CounterCategory 'Processor' -PerformanceCounterHash (New-IcingaPerformanceCounterArray '\Processor(*)\% processor time') -InstanceNameCleanupArray '_';
Name Value
---- -----
7 {% processor time}
Total {}
3 {% processor time}
4 {% processor time}
2 {% processor time}
1 {% processor time}
0 {% processor time}
6 {% processor time}
5 {% processor time}
.PARAMETER CounterCategory
The name of the category the sort algorithm will fetch the instances from for sorting
.PARAMETER PerformanceCounterHash
An array of Performance Counter objects provided by 'New-IcingaPerformanceCounterArray' to sort for
.PARAMETER InstanceNameCleanupArray
An array which will be used to remove string content from the sorted instances keys. For example '_' will change
'_Total' to 'Total'. Replacements are done in the order added to this array
.INPUTS
System.String
.OUTPUTS
System.Hashtable
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function New-IcingaPerformanceCounterStructure() function New-IcingaPerformanceCounterStructure()
{ {
param( param(

View file

@ -1,18 +1,67 @@
# <#
# This function will load all available Categories of Performance Counters .SYNOPSIS
# from the registry and outputs them. This will ensure we can fetch the real Fetches all available Performance Counter caregories on the system by using the
# english names instead of the localiced ones registry and returns the entire content as array. Allows to filter for certain
# categories only
.DESCRIPTION
Fetches all available Performance Counter caregories on the system by using the
registry and returns the entire content as array. Allows to filter for certain
categories only
.FUNCTIONALITY
Fetches all available Performance Counter caregories on the system by using the
registry and returns the entire content as array. Allows to filter for certain
categories only
.EXAMPLE
PS>Show-IcingaPerformanceCounterCategories;
System
Memory
Browser
Cache
Process
Thread
PhysicalDisk
...
.EXAMPLE
PS>Show-IcingaPerformanceCounterCategories -Filter 'Processor';
Processor
.EXAMPLE
PS>Show-IcingaPerformanceCounterCategories -Filter 'Processor', 'Memory';
Memory
Processor
.PARAMETER Filter
A array of counter categories to filter for. Supports wildcard search
.INPUTS
System.String
.OUTPUTS
System.Array
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Show-IcingaPerformanceCounterCategories() function Show-IcingaPerformanceCounterCategories()
{ {
$RegistryData = Get-ItemProperty ` param (
[array]$Filter = @()
);
[array]$Counters = @();
[array]$FilteredCounters = @();
# Load our cache if it does exist yet
$PerfCounterCache = Get-IcingaPerformanceCounterCacheItem 'Icinga:CachedCounterList';
# Create a cache for all available performance counter categories on the system
if ($null -eq $PerfCounterCache -or $PerfCounterCache.Count -eq 0) {
# Fetch the categories from the registry
$PerfCounterCache = Get-ItemProperty `
-Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009' ` -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009' `
-Name 'counter' | Select-Object -ExpandProperty Counter; -Name 'counter' | Select-Object -ExpandProperty Counter;
[array]$Counters = @();
# Now lets loop our registry data and fetch only for counter categories # Now lets loop our registry data and fetch only for counter categories
# Ignore everything else and drop the information # Ignore everything else and drop the information
foreach ($counter in $RegistryData) { foreach ($counter in $PerfCounterCache) {
# First filter out the ID's of the performance counter # First filter out the ID's of the performance counter
if (-Not ($counter -match "^[\d\.]+$") -And [string]::IsNullOrEmpty($counter) -eq $FALSE) { if (-Not ($counter -match "^[\d\.]+$") -And [string]::IsNullOrEmpty($counter) -eq $FALSE) {
# Now check if the value we got is a counter category # Now check if the value we got is a counter category
@ -22,5 +71,24 @@ function Show-IcingaPerformanceCounterCategories()
} }
} }
return $Counters; # Set our cache to the current list of categories
Add-IcingaPerformanceCounterCache -Counter 'Icinga:CachedCounterList' -Instances $Counters;
$PerfCounterCache = $Counters;
}
# In case we have no filter applied, simply return the entire list
if ($Filter.Count -eq 0) {
return $PerfCounterCache;
}
# In case we do, check each counter category against our filter element
foreach ($counter in $PerfCounterCache) {
foreach ($element in $Filter) {
if ($counter -like $element) {
$FilteredCounters += $counter;
}
}
}
return $FilteredCounters;
} }

View file

@ -1,7 +1,29 @@
# <#
# Provide the name of a category to fetch all available counters and .SYNOPSIS
# if there are any instances assigned to it Prints a list of all available Performance Counters for a specified category
# .DESCRIPTION
Prints a list of all available Performance Counters for a specified category
.FUNCTIONALITY
Prints a list of all available Performance Counters for a specified category
.EXAMPLE
PS>Show-IcingaPerformanceCounters -CounterCategory 'Processor';
\Processor(*)\dpcs queued/sec
\Processor(*)\% c1 time
\Processor(*)\% idle time
\Processor(*)\c3 transitions/sec
\Processor(*)\% c2 time
\Processor(*)\% dpc time
\Processor(*)\% privileged time
.PARAMETER CounterCategory
The name of the category to fetch availble counters for
.INPUTS
System.String
.OUTPUTS
System.Array
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Show-IcingaPerformanceCounters() function Show-IcingaPerformanceCounters()
{ {
param ( param (

View file

@ -0,0 +1,38 @@
<#
.SYNOPSIS
Test if a certain Performance Counter category exist on the systems and returns
either true or false depending on the state
.DESCRIPTION
Test if a certain Performance Counter category exist on the systems and returns
either true or false depending on the state
.FUNCTIONALITY
Test if a certain Performance Counter category exist on the systems and returns
either true or false depending on the state
.EXAMPLE
PS>Test-IcingaPerformanceCounterCategory -Category 'Processor';
True
.PARAMETER Category
The name of the category to test for
.INPUTS
System.String
.OUTPUTS
System.Boolean
.LINK
https://github.com/Icinga/icinga-powershell-framework
#>
function Test-IcingaPerformanceCounterCategory()
{
param (
[string]$Category
);
$Counters = Show-IcingaPerformanceCounterCategories -Filter $Category;
if ($Counters.Count -eq 0) {
return $FALSE;
}
return $TRUE;
}