From a2268ab3ecb6c1addffbedba0606aa6c95809dd4 Mon Sep 17 00:00:00 2001 From: "James Truher [MSFT]" Date: Tue, 25 Apr 2017 22:51:22 -0700 Subject: [PATCH] Add telemetry to the console host to report platform and version (#3620) This is limited to the console host and is not meant as generalized telemetry code for PowerShell Core. It will capture the GitCommitID and Platform Information when the console host starts. It enables opting out of sending telemetry. --- .gitignore | 3 + build.psm1 | 3 + .../Microsoft.PowerShell.ConsoleHost.csproj | 1 + .../host/msh/ConsoleHost.cs | 3 + .../host/msh/Telemetry.cs | 79 +++++++++++++++++++ src/powershell-unix/powershell-unix.csproj | 2 +- .../powershell-win-core.csproj | 2 +- 7 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs diff --git a/.gitignore b/.gitignore index 61dd6cb62f..bbf7d99f70 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,9 @@ dotnet-uninstall-debian-packages.sh # ignore the version file as it is generated at build time powershell.version +# ignore the telemetry semaphore file +DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY + # default location for produced nuget packages /nuget-artifacts diff --git a/build.psm1 b/build.psm1 index f3aed3395a..849c11a0e2 100644 --- a/build.psm1 +++ b/build.psm1 @@ -160,6 +160,9 @@ function Start-PSBuild { # save Git description to file for PowerShell to include in PSVersionTable git --git-dir="$PSScriptRoot/.git" describe --dirty --abbrev=60 > "$psscriptroot/powershell.version" + # create the telemetry flag file + $null = new-item -force -type file "$psscriptroot/DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY" + # simplify ParameterSetNames if ($PSCmdlet.ParameterSetName -eq 'FullCLR') { $FullCLR = $true diff --git a/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj b/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj index 9e0922018e..34eb0d2a32 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj +++ b/src/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj @@ -25,6 +25,7 @@ + diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 85702a4057..e1ab4f607d 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -257,6 +257,9 @@ namespace Microsoft.PowerShell s_theConsoleHost.UI.WriteWarningLine(preStartWarning); } + // Send startup telemetry for ConsoleHost startup + ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry(); + ClrFacade.StartProfileOptimization( s_theConsoleHost.LoadPSReadline() ? "StartupProfileData-Interactive" diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs new file mode 100644 index 0000000000..bf70135a5b --- /dev/null +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/Telemetry.cs @@ -0,0 +1,79 @@ +using System; +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.DataContracts; +using Microsoft.ApplicationInsights.Extensibility; +using System.Management.Automation; +using System.Security.Cryptography; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.IO; + +namespace Microsoft.PowerShell +{ + /// + /// send up telemetry for startup + /// + internal static class ApplicationInsightsTelemetry + { + // The semaphore file which indicates whether telemetry should be sent + // This is temporary code waiting on the acceptance and implementation of the configuration spec + // The name of the file by when present in $PSHOME will enable telemetry. + // If this file is not present, no telemetry will be sent. + private const string TelemetrySemaphoreFilename = "DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY"; + + // The path to the semaphore file which enables telemetry + private static string TelemetrySemaphoreFilePath = Path.Combine( + Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), + TelemetrySemaphoreFilename); + + // Telemetry client to be reused when we start sending more telemetry + private static TelemetryClient _telemetryClient = null; + + // Set this to true to reduce the latency of sending the telemetry + private static bool _developerMode = false; + + // PSCoreInsight2 telemetry key + private const string _psCoreTelemetryKey = "ee4b2115-d347-47b0-adb6-b19c2c763808"; + + static ApplicationInsightsTelemetry() + { + TelemetryConfiguration.Active.InstrumentationKey = _psCoreTelemetryKey; + TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = _developerMode; + } + + /// + /// Send the telemetry + /// + private static void SendTelemetry(string eventName, Dictionarypayload) + { + try + { + // if the semaphore file exists, try to send telemetry + if (Utils.NativeFileExists(TelemetrySemaphoreFilePath)) + { + if ( _telemetryClient == null ) + { + _telemetryClient = new TelemetryClient(); + } + _telemetryClient.TrackEvent(eventName, payload, null); + } + } + catch (Exception) + { + ; // Do nothing, telemetry can't be sent + } + } + + /// + /// Create the startup payload and send it up + /// + internal static void SendPSCoreStartupTelemetry() + { + var properties = new Dictionary(); + properties.Add("GitCommitID", PSVersionInfo.GitCommitId); + properties.Add("OSDescription", RuntimeInformation.OSDescription); + SendTelemetry("ConsoleHostStartup", properties); + } + } +} diff --git a/src/powershell-unix/powershell-unix.csproj b/src/powershell-unix/powershell-unix.csproj index 035bc332d2..60d501223e 100644 --- a/src/powershell-unix/powershell-unix.csproj +++ b/src/powershell-unix/powershell-unix.csproj @@ -19,7 +19,7 @@ PreserveNewest PreserveNewest - + PreserveNewest PreserveNewest diff --git a/src/powershell-win-core/powershell-win-core.csproj b/src/powershell-win-core/powershell-win-core.csproj index 71f16d5140..d17eb0f47a 100644 --- a/src/powershell-win-core/powershell-win-core.csproj +++ b/src/powershell-win-core/powershell-win-core.csproj @@ -23,7 +23,7 @@ PreserveNewest PreserveNewest - + PreserveNewest PreserveNewest