diff --git a/doc/31-Changelog.md b/doc/31-Changelog.md index 877569f..3f26dc8 100644 --- a/doc/31-Changelog.md +++ b/doc/31-Changelog.md @@ -20,6 +20,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * Adds new Cmdlet `Show-IcingaPerformanceCounterInstances` to display all available instances for Performance Counters * [#76](https://github.com/Icinga/icinga-powershell-framework/issues/76) Adds support to test for required .NET Framework Version 4.6.0 or above before trying to install the Icinga Agent * [#87](https://github.com/Icinga/icinga-powershell-framework/issues/87) Adds wrapper command to test new code or functionality of Framework and/or plugins +* [#88](https://github.com/Icinga/icinga-powershell-framework/issues/88) Adds Start/Stop timer functionality for performance analysis ### Bugfixes diff --git a/icinga-powershell-framework.psm1 b/icinga-powershell-framework.psm1 index d9dc53e..e277fcf 100644 --- a/icinga-powershell-framework.psm1 +++ b/icinga-powershell-framework.psm1 @@ -35,11 +35,13 @@ function Use-Icinga() $global:IcingaThreads = [hashtable]::Synchronized(@{}); $global:IcingaThreadContent = [hashtable]::Synchronized(@{}); $global:IcingaThreadPool = [hashtable]::Synchronized(@{}); + $global:IcingaTimers = [hashtable]::Synchronized(@{}); $global:IcingaDaemonData = [hashtable]::Synchronized( @{ 'IcingaThreads' = $global:IcingaThreads; 'IcingaThreadContent' = $global:IcingaThreadContent; 'IcingaThreadPool' = $global:IcingaThreadPool; + 'IcingaTimers' = $global:IcingaTimers; 'FrameworkRunningAsDaemon' = $Daemon; 'DebugMode' = $DebugMode; } diff --git a/lib/core/framework/Get-IcingaTimer.psm1 b/lib/core/framework/Get-IcingaTimer.psm1 new file mode 100644 index 0000000..960594f --- /dev/null +++ b/lib/core/framework/Get-IcingaTimer.psm1 @@ -0,0 +1,35 @@ +<# +.SYNOPSIS + Fetches a Stopwatch system object by a given name if initialised with Start-IcingaTimer +.DESCRIPTION + Fetches a Stopwatch system object by a given name if initialised with Start-IcingaTimer +.FUNCTIONALITY + Fetches a Stopwatch system object by a given name if initialised with Start-IcingaTimer +.EXAMPLE + PS>Get-IcingaTimer; +.EXAMPLE + PS>Get-IcingaTimer -Name 'My Test Timer'; +.PARAMETER Name + The name of a custom identifier to run mutliple timers at once +.INPUTS + System.String +.OUTPUTS + System.Diagnostics.Stopwatch +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Get-IcingaTimer() +{ + param ( + [string]$Name = 'DefaultTimer' + ); + + $TimerData = Get-IcingaHashtableItem -Key $Name -Hashtable $global:IcingaDaemonData.IcingaTimers; + + if ($null -eq $TimerData) { + return $null; + } + + return $TimerData.Timer; +} diff --git a/lib/core/framework/Show-IcingaTimer.psm1 b/lib/core/framework/Show-IcingaTimer.psm1 new file mode 100644 index 0000000..e6fd310 --- /dev/null +++ b/lib/core/framework/Show-IcingaTimer.psm1 @@ -0,0 +1,39 @@ +<# +.SYNOPSIS + Returns the spent time since Start-IcingaTimer was executed in seconds for + a specific timer name +.DESCRIPTION + Returns the spent time since Start-IcingaTimer was executed in seconds for + a specific timer name +.FUNCTIONALITY + Returns the spent time since Start-IcingaTimer was executed in seconds for + a specific timer name +.EXAMPLE + PS>Show-IcingaTimer; +.EXAMPLE + PS>Show-IcingaTimer -Name 'My Test Timer'; +.PARAMETER Name + The name of a custom identifier to run mutliple timers at once +.INPUTS + System.String +.OUTPUTS + Single +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Show-IcingaTimer() +{ + param ( + [string]$Name = 'DefaultTimer' + ); + + $TimerObject = Get-IcingaTimer -Name $Name; + + if ($null -eq $TimerObject) { + Write-IcingaConsoleNotice 'A timer with the name "{0}" does not exist' -Objects $Name; + return; + } + + return $TimerObject.Elapsed.TotalSeconds; +} diff --git a/lib/core/framework/Start-IcingaTimer.psm1 b/lib/core/framework/Start-IcingaTimer.psm1 new file mode 100644 index 0000000..af0874f --- /dev/null +++ b/lib/core/framework/Start-IcingaTimer.psm1 @@ -0,0 +1,45 @@ +<# +.SYNOPSIS + Start a new timer for a given name and stores it within the $globals section + of the Icinga PowerShell Framework +.DESCRIPTION + Start a new timer for a given name and stores it within the $globals section + of the Icinga PowerShell Framework +.FUNCTIONALITY + Start a new timer for a given name and stores it within the $globals section + of the Icinga PowerShell Framework +.EXAMPLE + PS>Start-IcingaTimer; +.EXAMPLE + PS>Start-IcingaTimer -Name 'My Test Timer'; +.PARAMETER Name + The name of a custom identifier to run mutliple timers at once +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Start-IcingaTimer() +{ + param ( + [string]$Name = 'DefaultTimer' + ); + + if ((Test-IcingaTimer)) { + Write-IcingaConsoleNotice 'The timer with the name "{0}" is already active' -Objects $Name; + return; + } + + # Load the library first + [System.Reflection.Assembly]::LoadWithPartialName("System.Diagnostics"); + $TimerObject = New-Object System.Diagnostics.Stopwatch; + $TimerObject.Start(); + + Add-IcingaHashtableItem -Key $Name -Value ([hashtable]::Synchronized( + @{ + 'Active' = $TRUE; + 'Timer' = $TimerObject; + } + )) -Hashtable $global:IcingaDaemonData.IcingaTimers -Override | Out-Null; +} diff --git a/lib/core/framework/Stop-IcingaTimer.psm1 b/lib/core/framework/Stop-IcingaTimer.psm1 new file mode 100644 index 0000000..06309e9 --- /dev/null +++ b/lib/core/framework/Stop-IcingaTimer.psm1 @@ -0,0 +1,44 @@ +<# +.SYNOPSIS + Stops a timer object started with Start-IcingaTimer for a specific + named timer +.DESCRIPTION + Stops a timer object started with Start-IcingaTimer for a specific + named timer +.FUNCTIONALITY + Stops a timer object started with Start-IcingaTimer for a specific + named timer +.EXAMPLE + PS>Stop-IcingaTimer; +.EXAMPLE + PS>Stop-IcingaTimer -Name 'My Test Timer'; +.PARAMETER Name + The name of a custom identifier to run mutliple timers at once +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Stop-IcingaTimer() +{ + param ( + [string]$Name = 'DefaultTimer' + ); + + $TimerObject = Get-IcingaTimer -Name $Name; + + if ($null -eq $TimerObject) { + return; + } + + if ($TimerObject.IsRunning) { + $TimerObject.Stop(); + } + Add-IcingaHashtableItem -Key $Name -Value ([hashtable]::Synchronized( + @{ + 'Active' = $FALSE; + 'Timer' = $TimerObject; + } + )) -Hashtable $global:IcingaDaemonData.IcingaTimers -Override | Out-Null; +} diff --git a/lib/core/framework/Test-IcingaTimer.psm1 b/lib/core/framework/Test-IcingaTimer.psm1 new file mode 100644 index 0000000..113c386 --- /dev/null +++ b/lib/core/framework/Test-IcingaTimer.psm1 @@ -0,0 +1,35 @@ +<# +.SYNOPSIS + Tests if a specific timer object is already present and started with Start-IcingaTimer +.DESCRIPTION + Tests if a specific timer object is already present and started with Start-IcingaTimer +.FUNCTIONALITY + Tests if a specific timer object is already present and started with Start-IcingaTimer +.EXAMPLE + PS>Test-IcingaTimer; +.EXAMPLE + PS>Test-IcingaTimer -Name 'My Test Timer'; +.PARAMETER Name + The name of a custom identifier to run mutliple timers at once +.INPUTS + System.String +.OUTPUTS + Boolean +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Test-IcingaTimer() +{ + param ( + [string]$Name = 'DefaultTimer' + ); + + $TimerData = Get-IcingaHashtableItem -Key $Name -Hashtable $global:IcingaDaemonData.IcingaTimers; + + if ($null -eq $TimerData) { + return $FALSE; + } + + return $TimerData.Active; +}