Framework/Listeners/Telemetry/ControlTelemetryHelper.ps1

Set-StrictMode -Version Latest

class ControlTelemetryHelper {
    hidden static [string] $TelemetrySessionId;
    hidden static [psobject] $EventBaseObject;

    hidden static $BaseEvent;

    static [void] Initialize() {
        if ($null -eq [ControlTelemetryHelper]::TelemetrySessionId) {
            [ControlTelemetryHelper]::TelemetrySessionId = [System.Guid]::NewGuid().ToString()
        }
    }

    hidden static [psobject] GetEventBaseObject([string] $eventName, [string] $action, [string] $utility) {
        $telemetryKey = [ControlTelemetryHelper]::GetControlTelemetryKey()
        $eventObj = "" | Select-Object data, iKey, name, tags, time
        $eventObj.iKey = $telemetryKey
        $eventObj.name = "Microsoft.ApplicationInsights." + $telemetryKey.Replace("-", "") + ".Event"
        $eventObj.time = "{{TIME}}"

        $eventObj.tags = "" | Select-Object ai.internal.sdkVersion
        $eventObj.tags.'ai.internal.sdkVersion' = "dotnet: 2.1.0.26048"

        $eventObj.data = "" | Select-Object baseData, baseType
        $eventObj.data.baseType = "EventData"
        $eventObj.data.baseData = "" | Select-Object ver, name, measurements, properties

        $eventObj.data.baseData.ver = 2
        $eventObj.data.baseData.name = $eventName

        $eventObj.data.baseData.measurements = New-Object 'system.collections.generic.dictionary[string,double]'
        $eventObj.data.baseData.properties = New-Object 'system.collections.generic.dictionary[string,string]'
        [ControlTelemetryHelper]::SetCommonProperties($eventObj, $action, $utility)
        return $eventObj;
    }

    hidden static [void] SetCommonProperties([psobject] $eventObj, [string] $action, [string] $utility) {
        $internalPrefix = "AzSdk"
        $notAvailable = "NA"
        try {
            $eventObj.data.baseData.properties.Add($internalPrefix + "Action", $action)
        }
        catch {
            $eventObj.data.baseData.properties.Add($internalPrefix + "Action", $notAvailable)
        }
        try {
            $eventObj.data.baseData.properties.Add($internalPrefix + "Utility", $utility)
        }
        catch {
            $eventObj.data.baseData.properties.Add($internalPrefix + "Utility", $notAvailable)
        }

        try {
            $rmContext = Get-AzureRmContext
            $eventObj.data.baseData.properties.Add($internalPrefix + "UserName", $rmContext.Account.Id)
        }
        catch {
            $eventObj.data.baseData.properties.Add($internalPrefix + "UserName", $notAvailable)
        }

        try {
            $rmContext = Get-AzureRmContext
            $eventObj.data.baseData.properties.Add($internalPrefix + "UserDomain", $rmContext.Tenant.TenantId)
        }
        catch {
            $eventObj.data.baseData.properties.Add($internalPrefix + "UserDomain", $notAvailable)
        }

        try {
            $eventObj.data.baseData.properties.Add($internalPrefix + "MachineName", [System.Environment]::MachineName)
        }
        catch {
            $eventObj.data.baseData.properties.Add($internalPrefix + "MachineName", $notAvailable)
        }
        [ControlTelemetryHelper]::Initialize()
        $eventObj.data.baseData.properties.Add($internalPrefix + "SessionId", `
                    [ControlTelemetryHelper]::TelemetrySessionId.ToString())

        $eventObj.data.baseData.properties.Add($internalPrefix + "PSVersion", `
                    (Get-Variable -Name PSVersionTable).Value.PSVersion.ToString())   
    }

    static [void] PublishEvent([string] $eventName, [hashtable] $properties, [hashtable] $metrics, [string] $action, [string] $utility) {
        try {
            if(![ControlTelemetryHelper]::IsControlTelemetryEnabled()){ return; };

            $eventObj = [ControlTelemetryHelper]::GetEventBaseObject($eventName, $action, $utility);
            $metrics.Keys | ForEach-Object {
                try {
                    $eventObj.data.baseData.measurements.Add($_ , $metrics[$_])
                }
                catch {}
            }
            $properties.Keys | ForEach-Object {
                try {
                    $eventObj.data.baseData.properties.Add($_ , $properties[$_])
                }
                catch {}
            }
            $eventJson = $(ConvertTo-Json $eventObj -Depth 100 -Compress).Replace("{{TIME}}", [datetime]::UtcNow.ToString("o")) 

            Invoke-WebRequest -Uri "https://dc.services.visualstudio.com/v2/track" `
                                -Method Post `
                                -ContentType "application/x-json-stream" `
                                -Body $eventJson `
                                -UseBasicParsing | Out-Null
        }
        catch {
        }
    }

    hidden static [string] GetControlTelemetryKey()
    {
        $settings = [ConfigurationManager]::GetAzSdkConfigData();
        $telemetryKey = $settings.ControlTelemetryKey
        [guid]$key = [guid]::NewGuid()
        if([guid]::TryParse($telemetryKey, [ref] $key) -and ![guid]::Empty.Equals($key))
        {
            return $telemetryKey;
        }
        return [ConfigurationManager]::GetAzSdkSettings().LocalControlTelemetryKey;
    }

    hidden static [bool] IsControlTelemetryEnabled()
    {
        $settings = [ConfigurationManager]::GetAzSdkConfigData();
        $telemetryKey = $settings.ControlTelemetryKey
        [guid]$key = [guid]::NewGuid()
        if([guid]::TryParse($telemetryKey, [ref] $key) -and ![guid]::Empty.Equals($key))
        {
            return $settings.EnableControlTelemetry;
        }
        return [ConfigurationManager]::GetAzSdkSettings().LocalEnableControlTelemetry;
    }
}