2016-03-25 13:15:36 -07:00
using System ;
using System.Collections.Generic ;
using Microsoft.ApplicationInsights ;
using Microsoft.Extensions.PlatformAbstractions ;
2016-03-30 17:21:31 -07:00
using System.Diagnostics ;
2016-03-25 13:15:36 -07:00
namespace Microsoft.DotNet.Cli.Utils
{
2016-03-31 16:37:40 -07:00
public class Telemetry : ITelemetry
2016-03-25 13:15:36 -07:00
{
2016-04-04 16:18:47 -07:00
private bool _isInitialized = false ;
private TelemetryClient _client = null ;
2016-03-25 13:15:36 -07:00
2016-04-04 16:18:47 -07:00
private Dictionary < string , string > _commonProperties = null ;
private Dictionary < string , double > _commonMeasurements = null ;
2016-03-25 13:15:36 -07:00
2016-03-30 17:21:31 -07:00
private const string InstrumentationKey = "74cc1c9e-3e6e-4d05-b3fc-dde9101d0254" ;
2016-03-28 17:17:21 -07:00
private const string TelemetryOptout = "DOTNET_CLI_TELEMETRY_OPTOUT" ;
private const string OSVersion = "OS Version" ;
private const string OSPlatform = "OS Platform" ;
private const string RuntimeId = "Runtime Id" ;
private const string ProductVersion = "Product Version" ;
public Telemetry ( )
2016-03-25 13:15:36 -07:00
{
2016-03-28 17:17:21 -07:00
bool optout = Env . GetEnvironmentVariableAsBool ( TelemetryOptout ) ;
2016-03-25 13:15:36 -07:00
2016-03-28 17:17:21 -07:00
if ( optout )
2016-03-31 16:37:40 -07:00
{
2016-03-25 13:15:36 -07:00
return ;
2016-03-31 16:37:40 -07:00
}
2016-03-25 13:15:36 -07:00
try
{
_client = new TelemetryClient ( ) ;
2016-03-28 17:17:21 -07:00
_client . InstrumentationKey = InstrumentationKey ;
2016-03-25 13:15:36 -07:00
_client . Context . Session . Id = Guid . NewGuid ( ) . ToString ( ) ;
var runtimeEnvironment = PlatformServices . Default . Runtime ;
_client . Context . Device . OperatingSystem = runtimeEnvironment . OperatingSystem ;
_commonProperties = new Dictionary < string , string > ( ) ;
2016-03-28 17:17:21 -07:00
_commonProperties . Add ( OSVersion , runtimeEnvironment . OperatingSystemVersion ) ;
_commonProperties . Add ( OSPlatform , runtimeEnvironment . OperatingSystemPlatform . ToString ( ) ) ;
_commonProperties . Add ( RuntimeId , runtimeEnvironment . GetRuntimeIdentifier ( ) ) ;
_commonProperties . Add ( ProductVersion , Product . Version ) ;
2016-03-25 13:15:36 -07:00
_commonMeasurements = new Dictionary < string , double > ( ) ;
_isInitialized = true ;
}
2016-03-30 17:21:31 -07:00
catch ( Exception )
{
// we dont want to fail the tool if telemetry fais. We should be able to detect abnormalities from data
// at the server end
2016-04-04 16:18:47 -07:00
Debug . Fail ( "Exception during telemetry initialization" ) ;
2016-03-30 17:21:31 -07:00
}
2016-03-25 13:15:36 -07:00
}
2016-03-31 16:37:40 -07:00
public void TrackEvent ( string eventName , IDictionary < string , string > properties , IDictionary < string , double > measurements )
2016-03-25 13:15:36 -07:00
{
if ( ! _isInitialized )
2016-03-31 16:37:40 -07:00
{
2016-03-25 13:15:36 -07:00
return ;
2016-03-31 16:37:40 -07:00
}
2016-03-25 13:15:36 -07:00
2016-03-28 17:17:21 -07:00
Dictionary < string , double > eventMeasurements = GetEventMeasures ( measurements ) ;
Dictionary < string , string > eventProperties = GetEventProperties ( properties ) ;
try
2016-03-25 13:15:36 -07:00
{
2016-03-31 16:37:40 -07:00
_client . TrackEvent ( eventName , eventProperties , eventMeasurements ) ;
2016-03-28 17:17:21 -07:00
_client . Flush ( ) ;
2016-03-25 13:15:36 -07:00
}
2016-04-04 16:18:47 -07:00
catch ( Exception )
{
Debug . Fail ( "Exception during TrackEvent" ) ;
}
2016-03-28 17:17:21 -07:00
}
2016-03-25 13:15:36 -07:00
2016-03-30 17:21:31 -07:00
2016-03-28 17:17:21 -07:00
private Dictionary < string , double > GetEventMeasures ( IDictionary < string , double > measurements )
{
2016-03-25 13:15:36 -07:00
Dictionary < string , double > eventMeasurements = new Dictionary < string , double > ( _commonMeasurements ) ;
if ( measurements ! = null )
{
2016-03-31 16:37:40 -07:00
foreach ( var measurement in measurements )
2016-03-25 13:15:36 -07:00
{
2016-03-31 16:37:40 -07:00
if ( eventMeasurements . ContainsKey ( measurement . Key ) )
{
eventMeasurements [ measurement . Key ] = measurement . Value ;
}
2016-03-25 13:15:36 -07:00
else
2016-03-31 16:37:40 -07:00
{
eventMeasurements . Add ( measurement . Key , measurement . Value ) ;
}
2016-03-25 13:15:36 -07:00
}
}
2016-03-28 17:17:21 -07:00
return eventMeasurements ;
}
2016-03-25 13:15:36 -07:00
2016-03-28 17:17:21 -07:00
private Dictionary < string , string > GetEventProperties ( IDictionary < string , string > properties )
{
if ( properties ! = null )
2016-03-25 13:15:36 -07:00
{
2016-04-04 16:18:47 -07:00
var eventProperties = new Dictionary < string , string > ( _commonProperties ) ;
2016-03-31 16:37:40 -07:00
foreach ( var property in properties )
2016-03-28 17:17:21 -07:00
{
2016-03-31 16:37:40 -07:00
if ( eventProperties . ContainsKey ( property . Key ) )
{
eventProperties [ property . Key ] = property . Value ;
}
2016-03-28 17:17:21 -07:00
else
2016-03-31 16:37:40 -07:00
{
eventProperties . Add ( property . Key , property . Value ) ;
}
2016-03-28 17:17:21 -07:00
}
2016-04-04 16:18:47 -07:00
return eventProperties ;
}
else
{
return _commonProperties ;
2016-03-25 13:15:36 -07:00
}
}
}
}