navcontainerhelper/TelemetryHelper.ps1

251 строка
11 KiB
PowerShell

function FormatValue {
Param(
$value
)
if ($value -eq $null) {
"[null]"
}
elseif ($value -is [switch]) {
$value.IsPresent
}
elseif ($value -is [boolean]) {
$value
}
elseif ($value -is [SecureString]) {
"[SecureString]"
}
elseif ($value -is [PSCredential]) {
"[PSCredential]"
}
elseif ($value -is [string]) {
if (($value -like "https:*" -or $value -like "http:*") -and ($value.Contains('?'))) {
"$($value.Split('?')[0])?[parameters]"
}
else {
"$value"
}
}
elseif ($value -is [System.Collections.IDictionary]) {
$str = ""
$value.GetEnumerator() | ForEach-Object {
if ($str) { $str += "`n " } else { $str = "{`n" }
$str += "$($_.Key): $(FormatValue -value $_.Value)"
}
"$str`n}"
}
elseif ($value -is [System.Collections.IEnumerable]) {
$str = ""
$value.GetEnumerator() | ForEach-Object {
if ($str) { $str += "`n " } else { $str = "[`n" }
$str += "$(FormatValue -value $_)"
}
"$str`n]"
}
else {
$value
}
}
function AddTelemetryProperty {
Param(
$telemetryScope,
$key,
$value
)
if ($telemetryScope) {
$value = FormatValue -value $value
if ($telemetry.Debug) {
Write-Host -ForegroundColor Yellow "Telemetry scope $($telemetryScope.Name), add property $key = '$value', type = $($value.GetType())"
}
if ($telemetryScope.properties.ContainsKey($Key)) {
$telemetryScope.properties."$key" += "`n$value"
}
else {
$telemetryScope.properties.Add($key, $value)
}
}
}
function InitTelemetryScope {
Param(
[string] $name,
[switch] $always,
[string[]] $includeParameters = @(),
$parameterValues = $null
)
$includeParameters = "*"
if ($telemetry.Client) {
if ($bcContainerHelperConfig.TelemetryConnectionString) {
if ($telemetry.Client.TelemetryConfiguration.DisableTelemetry -or $telemetry.Client.TelemetryConfiguration.ConnectionString -ne $bcContainerHelperConfig.TelemetryConnectionString) {
if ($bcContainerHelperConfig.TelemetryConnectionString) {
try {
$telemetry.Client.TelemetryConfiguration.ConnectionString = $bcContainerHelperConfig.TelemetryConnectionString
$telemetry.Client.TelemetryConfiguration.DisableTelemetry = $false
if ($telemetry.Debug) {
Write-Host -ForegroundColor Yellow "Telemetry client initialized"
}
}
catch {
$telemetry.Client.TelemetryConfiguration.DisableTelemetry = $true
}
}
}
if ($telemetry.Client.IsEnabled() -and ($always -or ($telemetry.CorrelationId -eq ""))) {
$CorrelationId = [GUID]::NewGuid().ToString()
Start-Transcript -Path (Join-Path $env:TEMP $CorrelationId) | Out-Null
if ($telemetry.Debug) {
Write-Host -ForegroundColor Yellow "Init telemetry scope $name"
}
if ($telemetry.TopId -eq "") { $telemetry.TopId = $CorrelationId }
$scope = @{
"Name" = $name
"StartTime" = [DateTime]::Now
"SeverityLevel" = 1
"Properties" = [Collections.Generic.Dictionary[string, string]]::new()
"CorrelationId" = $CorrelationId
"ParentId" = $telemetry.CorrelationId
"TopId" = $telemetry.TopId
"Emitted" = $false
}
$telemetry.CorrelationId = $CorrelationId
if ($includeParameters) {
$parameterValues.GetEnumerator() | ForEach-Object {
$includeParameter = $false
$key = $_.key
$includeParameters | ForEach-Object { if ($key -like $_) { $includeParameter = $true } }
if ($includeParameter) {
AddTelemetryProperty -telemetryScope $scope -key "Parameter[$Key]" -value $_.Value
}
}
}
AddTelemetryProperty -telemetryScope $scope -key "BcContainerHelperVersion" -value $BcContainerHelperVersion
AddTelemetryProperty -telemetryScope $scope -key "IsAdministrator" -value $isAdministrator
AddTelemetryProperty -telemetryScope $scope -key "StackTrace" -value (Get-PSCallStack | % { "$($_.Command) at $($_.Location)" }) -join "`n"
$scope
}
}
else {
$telemetry.Client.TelemetryConfiguration.DisableTelemetry = $true
}
}
}
function TrackTrace {
Param(
$telemetryScope
)
if ($telemetryScope -and !$telemetryScope.Emitted) {
if ($telemetry.Client.IsEnabled() -and ($telemetryScope.CorrelationId -eq $telemetry.CorrelationId)) {
if ($telemetry.Debug) {
Write-Host -ForegroundColor Yellow "Emit telemetry trace, scope $($telemetryScope.Name)"
}
$telemetry.CorrelationId = $telemetryScope.ParentId
if ($telemetry.CorrelationId -eq "") {
$telemetry.TopId = ""
}
$telemetryScope.Emitted = $true
$telemetryScope.Properties.Add("Duration", [DateTime]::Now.Subtract($telemetryScope.StartTime).TotalSeconds)
try {
Stop-Transcript | Out-Null
$transcript = (@(Get-Content -Path (Join-Path $env:TEMP $telemetryScope.CorrelationId)) | select -skip 18 | select -skiplast 4) -join "`n"
if ($transcript.Length -gt 32000) {
$transcript = "$($transcript.SubString(0,16000))`n`n...`n`n$($transcript.SubString($transcript.Length-16000))"
}
Remove-Item -Path (Join-Path $env:TEMP $telemetryScope.CorrelationId)
}
catch {
$transcript = ""
}
$traceTelemetry = $telemetry.Client.GetType().Assembly.CreateInstance('Microsoft.ApplicationInsights.DataContracts.TraceTelemetry')
$traceTelemetry.Message = "$($telemetryScope.Name)`n$transcript"
$traceTelemetry.SeverityLevel = $telemetryScope.SeverityLevel
$telemetryScope.Properties.GetEnumerator() | ForEach-Object {
[void]$traceTelemetry.Properties.TryAdd($_.Key, $_.Value)
}
$traceTelemetry.Context.Operation.Name = $telemetryScope.Name
$traceTelemetry.Context.Operation.Id = $telemetryScope.CorrelationId
$traceTelemetry.Context.Operation.ParentId = $telemetryScope.ParentId
$telemetry.Client.TrackTrace($traceTelemetry)
$telemetry.Client.Flush()
}
}
}
function TrackException {
Param(
$telemetryScope,
$errorRecord
)
TrackException -telemetryScope $telemetryScope -exception $errorRecord.Exception -scriptStackTrace $errorRecord.scriptStackTrace
}
function TrackException {
Param(
$telemetryScope,
$exception,
$scriptStackTrace = $null
)
if ($telemetryScope -and !$telemetryScope.Emitted) {
if ($telemetry.Client.IsEnabled() -and ($telemetryScope.CorrelationId -eq $telemetry.CorrelationId)) {
if ($telemetry.Debug) {
Write-Host -ForegroundColor Yellow "Emit telemetry exception, scope $($telemetryScope.Name)"
}
$telemetry.CorrelationId = $telemetryScope.ParentId
if ($telemetry.CorrelationId -eq "") {
$telemetry.TopId = ""
}
$telemetryScope.Emitted = $true
$telemetryScope.Properties.Add("Duration", [DateTime]::Now.Subtract($telemetryScope.StartTime).TotalSeconds)
if ($scriptStackTrace) {
$telemetryScope.Properties.Add("Error StackTrace", $scriptStackTrace)
}
if ($exception) {
$telemetryScope.Properties.Add("Error Message", $exception.Message)
}
try {
Stop-Transcript | Out-Null
$transcript = (@(Get-Content -Path (Join-Path $env:TEMP $telemetryScope.CorrelationId)) | select -skip 18 | select -skiplast 4) -join "`n"
if ($transcript.Length -gt 32000) {
$transcript = "$($transcript.SubString(0,16000))`n`n...`n`n$($transcript.SubString($transcript.Length-16000))"
}
Remove-Item -Path (Join-Path $env:TEMP $telemetryScope.CorrelationId)
}
catch {
$transcript = ""
}
# emit trace telemetry with Error info
$traceTelemetry = $telemetry.Client.GetType().Assembly.CreateInstance('Microsoft.ApplicationInsights.DataContracts.TraceTelemetry')
$traceTelemetry.Message = "$($telemetryScope.Name)`n$transcript"
$traceTelemetry.SeverityLevel = $telemetryScope.SeverityLevel
$telemetryScope.Properties.GetEnumerator() | ForEach-Object {
[void]$traceTelemetry.Properties.TryAdd($_.Key, $_.Value)
}
$traceTelemetry.Context.Operation.Name = $telemetryScope.Name
$traceTelemetry.Context.Operation.Id = $telemetryScope.CorrelationId
$traceTelemetry.Context.Operation.ParentId = $telemetryScope.ParentId
$telemetry.Client.TrackTrace($traceTelemetry)
# emit exception telemetry
$exceptionTelemetry = $telemetry.Client.GetType().Assembly.CreateInstance('Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry')
$exceptionTelemetry.Message = "$($telemetryScope.Name)`n$transcript"
$exceptionTelemetry.SeverityLevel = $telemetryScope.SeverityLevel
$telemetryScope.Properties.GetEnumerator() | ForEach-Object {
[void]$exceptionTelemetry.Properties.TryAdd($_.Key, $_.Value)
}
$exceptionTelemetry.Context.Operation.Name = $telemetryScope.Name
$exceptionTelemetry.Context.Operation.Id = $telemetryScope.CorrelationId
$exceptionTelemetry.Context.Operation.ParentId = $telemetryScope.ParentId
$telemetry.Client.TrackException($exceptionTelemetry)
$telemetry.Client.Flush()
}
}
}