From 008b4920f1eb659a9b0b0cbcd9a2890d41597d7f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 12 Jan 2022 09:53:28 +0100 Subject: [PATCH] Adds exeception detail reporting --- doc/100-General/10-Changelog.md | 1 + .../logging/Get-IcingaExceptionString.psm1 | 60 +++++++++++++++++++ .../logging/Write-IcingaDebugMessage.psm1 | 7 ++- .../logging/Write-IcingaEventMessage.psm1 | 9 +-- 4 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 lib/core/logging/Get-IcingaExceptionString.psm1 diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index 35fb388..cac7cac 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -27,6 +27,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#388](https://github.com/Icinga/icinga-powershell-framework/issues/388) Improves performance for testing if `Add-Type` functions have been added, by adding an internal test for newly introduced environment variables within a PowerShell session * [#417](https://github.com/Icinga/icinga-powershell-framework/issues/417) Adds support to allow the force creation of Icinga Agent certificates, even when they are already present on the system over Icinga Management Console installation +* [#426](https://github.com/Icinga/icinga-powershell-framework/pull/426) Adds a new feature to EventLog writer, allowing to parse an exception report to identity the exact root cause and location, on where the error occurred in first place. ## 1.7.1 (2021-11-11) diff --git a/lib/core/logging/Get-IcingaExceptionString.psm1 b/lib/core/logging/Get-IcingaExceptionString.psm1 new file mode 100644 index 0000000..55fa9e8 --- /dev/null +++ b/lib/core/logging/Get-IcingaExceptionString.psm1 @@ -0,0 +1,60 @@ +function Get-IcingaExceptionString() +{ + param ( + $ExceptionObject = $null + ); + + if ($null -eq $ExceptionObject) { + return ''; + } + + $ExceptionStack = New-Object -TypeName 'System.Text.StringBuilder'; + + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Icinga for Windows exception report:') | Out-Null; + + if ([string]::IsNullOrEmpty($ExceptionObject.Exception.Message) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Exception Message:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.Exception.Message) | Out-Null; + } + if ([string]::IsNullOrEmpty($ExceptionObject.InvocationInfo.InvocationName) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Invocation Name:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.InvocationInfo.InvocationName) | Out-Null; + } + if ([string]::IsNullOrEmpty($ExceptionObject.InvocationInfo.CommandOrigin) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Command Origin:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.InvocationInfo.CommandOrigin) | Out-Null; + } + if ([string]::IsNullOrEmpty($ExceptionObject.InvocationInfo.ScriptLineNumber) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Script Line Number:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.InvocationInfo.ScriptLineNumber) | Out-Null; + } + if ([string]::IsNullOrEmpty($ExceptionObject.InvocationInfo.PositionMessage) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Exact Position:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.InvocationInfo.PositionMessage) | Out-Null; + } + if ([string]::IsNullOrEmpty($ExceptionObject.Exception.StackTrace) -eq $FALSE) { + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('StackTrace:') | Out-Null; + $ExceptionStack.AppendLine($ExceptionObject.Exception.StackTrace) | Out-Null; + } + + $CallStack = Get-PSCallStack; + + $ExceptionStack.AppendLine('') | Out-Null; + $ExceptionStack.AppendLine('Call Stack:') | Out-Null; + if ($CallStack.Count -gt 11) { + $ExceptionStack.AppendLine(($CallStack[0..10] | Out-String)) | Out-Null; + } else { + $ExceptionStack.AppendLine(($CallStack | Out-String)) | Out-Null; + } + $ExceptionStack.Remove($ExceptionStack.Length - 8, 8) | Out-Null; + + return $ExceptionStack.ToString(); +} diff --git a/lib/core/logging/Write-IcingaDebugMessage.psm1 b/lib/core/logging/Write-IcingaDebugMessage.psm1 index 419e290..362381b 100644 --- a/lib/core/logging/Write-IcingaDebugMessage.psm1 +++ b/lib/core/logging/Write-IcingaDebugMessage.psm1 @@ -1,8 +1,9 @@ function Write-IcingaDebugMessage() { - param( + param ( [string]$Message, - [array]$Objects = @() + [array]$Objects = @(), + $ExceptionObject = $null ); if ([string]::IsNullOrEmpty($Message)) { @@ -16,5 +17,5 @@ function Write-IcingaDebugMessage() [array]$DebugContent = @($Message); $DebugContent += $Objects; - Write-IcingaEventMessage -EventId 1000 -Namespace 'Framework' -Objects $DebugContent; + Write-IcingaEventMessage -EventId 1000 -Namespace 'Framework' -ExceptionObject $ExceptionObject -Objects $DebugContent; } diff --git a/lib/core/logging/Write-IcingaEventMessage.psm1 b/lib/core/logging/Write-IcingaEventMessage.psm1 index 0f15538..dcac2aa 100644 --- a/lib/core/logging/Write-IcingaEventMessage.psm1 +++ b/lib/core/logging/Write-IcingaEventMessage.psm1 @@ -3,7 +3,8 @@ function Write-IcingaEventMessage() param ( [int]$EventId = 0, [string]$Namespace = $null, - [array]$Objects = @() + [array]$Objects = @(), + $ExceptionObject = $null ); if ($EventId -eq 0 -Or [string]::IsNullOrEmpty($Namespace)) { @@ -25,7 +26,7 @@ function Write-IcingaEventMessage() if ($Objects.Count -eq 0) { $ObjectDump = [string]::Format( - '{0}{0}No additional object details provided.', + '{0}No additional object details provided.', (New-IcingaNewLine) ); } @@ -39,12 +40,12 @@ function Write-IcingaEventMessage() } [string]$EventLogMessage = [string]::Format( - '{0}{1}{1}{2}{1}{1}Object dumps if available:{1}{3}', + '{0}{1}{1}{2}{3}{1}{1}Object details:{1}{4}', $Message, (New-IcingaNewLine), $Details, + (Get-IcingaExceptionString -ExceptionObject $ExceptionObject), $ObjectDump - ); if ($null -eq $EntryType -Or $null -eq $Message) {