Private/ConvertTo-AACExceptionRecord.ps1
|
function ConvertTo-AACExceptionRecord { <# .SYNOPSIS Flattens one exception row - from a workspace's AppExceptions table or Application Insights' exceptions table - into an AAC.ApplicationInsightsException object. .DESCRIPTION Both schemas give the same properties. The details array (one entry per exception in the chain) becomes the outermost entry's message, type and severity level, the count of entries, and the top stack frame; custom properties become one "key=value; ..." column. #> [CmdletBinding()] param( [Parameter(Mandatory)] [System.Collections.IDictionary] $Row, [string] $Source ) # A column by any of its names (workspace or classic schema). $get = { param([string[]] $Names) foreach ($name in $Names) { if ($Row.Contains($name) -and $null -ne $Row[$name] -and [string]$Row[$name] -ne '') { return $Row[$name] } } $null } # Dynamic columns arrive as JSON text. $parse = { param($Value) if ($Value -is [string] -and $Value.Trim() -match '^[\[{]') { try { return ConvertFrom-Json -InputObject $Value -AsHashtable -ErrorAction Stop } catch { return $Value } } $Value } $text = { param($Value) if ($null -eq $Value) { '' } else { [string]$Value } } $severityNames = @('Verbose', 'Information', 'Warning', 'Error', 'Critical') $time = & $get 'TimeGenerated', 'timestamp' $when = $null if ($time -is [datetime]) { $when = $time.ToUniversalTime() } elseif ($time) { $parsed = [datetimeoffset]::MinValue if ([datetimeoffset]::TryParse([string]$time, [cultureinfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::AssumeUniversal, [ref]$parsed)) { $when = $parsed.UtcDateTime } } $level = & $get 'SeverityLevel', 'severityLevel' $levelNumber = if ($null -ne $level -and [string]$level -match '^\d+$') { [int]$level } else { $null } $details = @(& $parse (& $get 'Details', 'details') | Where-Object { $_ -is [System.Collections.IDictionary] }) $first = if ($details.Count) { $details[0] } else { @{} } $frame = $null if ($first.Contains('parsedStack') -and @($first['parsedStack']).Count) { $frame = @($first['parsedStack'])[0] } $stackTop = if ($frame -is [System.Collections.IDictionary]) { $at = & $text $frame['method'] if ($frame['fileName']) { $at += " ($($frame['fileName'])$(if ($frame['line']) { ":$($frame['line'])" }))" } $at } else { '' } $properties = & $parse (& $get 'Properties', 'customDimensions') $propertyText = if ($properties -is [System.Collections.IDictionary]) { (@($properties.Keys | Sort-Object | ForEach-Object { "$_=$($properties[$_])" }) -join '; ') } else { & $text $properties } $type = & $text (& $get 'ExceptionType', 'type', 'OuterType', 'outerType') $message = & $text (& $get 'Message', 'message', 'OuterMessage', 'outerMessage', 'InnermostMessage', 'innermostMessage') [pscustomobject]@{ PSTypeName = 'AAC.ApplicationInsightsException' TimeGenerated = $when Severity = $(if ($null -ne $levelNumber -and $levelNumber -lt $severityNames.Count) { $severityNames[$levelNumber] } else { & $text $level }) SeverityLevel = $levelNumber ExceptionType = $type Message = $message OuterType = & $text (& $get 'OuterType', 'outerType') OuterMessage = & $text (& $get 'OuterMessage', 'outerMessage') InnermostType = & $text (& $get 'InnermostType', 'innermostType') InnermostMessage = & $text (& $get 'InnermostMessage', 'innermostMessage') DetailType = & $text $first['type'] DetailMessage = & $text $first['message'] DetailSeverityLevel = & $text $first['severityLevel'] DetailCount = $details.Count StackTop = $stackTop Method = & $text (& $get 'Method', 'method', 'InnermostMethod', 'innermostMethod') Assembly = & $text (& $get 'Assembly', 'assembly', 'InnermostAssembly', 'innermostAssembly') ProblemId = & $text (& $get 'ProblemId', 'problemId') HandledAt = & $text (& $get 'HandledAt', 'handledAt') OperationName = & $text (& $get 'OperationName', 'operation_Name') OperationId = & $text (& $get 'OperationId', 'operation_Id') AppRoleName = & $text (& $get 'AppRoleName', 'cloud_RoleName', 'appName') AppRoleInstance = & $text (& $get 'AppRoleInstance', 'cloud_RoleInstance') AppVersion = & $text (& $get 'AppVersion', 'application_Version') ClientType = & $text (& $get 'ClientType', 'client_Type') ClientCountryOrRegion = & $text (& $get 'ClientCountryOrRegion', 'client_CountryOrRegion') ClientCity = & $text (& $get 'ClientCity', 'client_City') SdkVersion = & $text (& $get 'SDKVersion', 'sdkVersion') ItemCount = $(if ((& $get 'ItemCount', 'itemCount') -as [int]) { [int](& $get 'ItemCount', 'itemCount') } else { 1 }) CustomProperties = $propertyText Source = $Source ResourceId = & $text (& $get '_ResourceId') } } |