Skip to content

Added telemetry prompt and command and improved telemetry Flushing [Delivers #111575840] #1703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/CLU/Commands.Common.Authentication/Models/AzureRMProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,21 @@ public AzureRMProfile(IDataStore dataStore)
[JsonIgnore]
public string ProfilePath { get; private set; }

/// <summary>
/// When set to true, collects telemetry information.
/// </summary>
public bool? IsTelemetryCollectionEnabled { get; set; }

private void Load(string path)
{
this.ProfilePath = path;
if (_dataStore.FileExists(ProfilePath))
{
string contents = _dataStore.ReadFileAsText(ProfilePath);
AzureRMProfile profile = JsonConvert.DeserializeObject<AzureRMProfile>(contents);
Debug.Assert(profile != null);
this.Context = profile.Context;
this.Environments = profile.Environments;
JsonConvert.PopulateObject(contents, this);
}
}


/// <summary>
/// Writes profile to the disk it was opened from disk.
/// </summary>
Expand Down
59 changes: 3 additions & 56 deletions src/CLU/Commands.Common/AzureDataCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,64 +60,11 @@ public AzureRMProfile RMProfile
get { return GetSessionVariableValue<PSAzureProfile>(AzurePowerShell.ProfileVariable, null); }
}

protected override void SaveDataCollectionProfile()
protected override bool IsTelemetryCollectionEnabled
{
if (_dataCollectionProfile == null)
{
InitializeDataCollectionProfile();
}

string fileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
var contents = JsonConvert.SerializeObject(_dataCollectionProfile);
if (!DataStore.DirectoryExists(AzurePowerShell.ProfileDirectory))
{
DataStore.CreateDirectory(AzurePowerShell.ProfileDirectory);
}
DataStore.WriteFile(fileFullPath, contents);
WriteWarning(string.Format(Resources.DataCollectionSaveFileInformation, fileFullPath));
}

protected override void PromptForDataCollectionProfileIfNotExists()
{
// Initialize it from the environment variable or profile file.
InitializeDataCollectionProfile();

if (!_dataCollectionProfile.EnableAzureDataCollection.HasValue && CheckIfInteractive())
get
{
WriteWarning(Resources.DataCollectionPrompt);

const double timeToWaitInSeconds = 60;
var status = string.Format(Resources.DataCollectionConfirmTime, timeToWaitInSeconds);
ProgressRecord record = new ProgressRecord(0, Resources.DataCollectionActivity, status);

var startTime = DateTime.Now;
var endTime = DateTime.Now;
//double elapsedSeconds = 0;

//while (!this.Host.UI.RawUI.KeyAvailable && elapsedSeconds < timeToWaitInSeconds)
//{
// Thread.Sleep(TimeSpan.FromMilliseconds(10));
// endTime = DateTime.Now;

// elapsedSeconds = (endTime - startTime).TotalSeconds;
// record.PercentComplete = ((int) elapsedSeconds*100/(int) timeToWaitInSeconds);
// WriteProgress(record);
//}

bool enabled = false;
//if (this.Host.UI.RawUI.KeyAvailable)
//{
// KeyInfo keyInfo =
// this.Host.UI.RawUI.ReadKey(ReadKeyOptions.NoEcho | ReadKeyOptions.AllowCtrlC |
// ReadKeyOptions.IncludeKeyDown);
// enabled = (keyInfo.Character == 'Y' || keyInfo.Character == 'y');
//}

_dataCollectionProfile.EnableAzureDataCollection = enabled;

WriteWarning(enabled ? Resources.DataCollectionConfirmYes : Resources.DataCollectionConfirmNo);

SaveDataCollectionProfile();
return false;
}
}

Expand Down
131 changes: 12 additions & 119 deletions src/CLU/Commands.Common/AzurePSCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ namespace Microsoft.Azure.Commands.Utilities.Common
public abstract class AzurePSCmdlet : PSCmdlet, IDisposable
{
protected readonly ConcurrentQueue<string> _debugMessages;


private DebugStreamTraceListener _adalListener;
protected static AzurePSDataCollectionProfile _dataCollectionProfile = null;
protected static string _errorRecordFolderPath = null;
protected const string _fileTimeStampSuffixFormat = "yyyy-MM-dd-THH-mm-ss-fff";
protected string _clientRequestId = Guid.NewGuid().ToString();
Expand All @@ -56,7 +53,8 @@ public abstract class AzurePSCmdlet : PSCmdlet, IDisposable

protected AzurePSQoSEvent QosEvent;

protected virtual bool IsUsageMetricEnabled {
protected virtual bool IsUsageMetricEnabled
{
get { return true; }
}

Expand All @@ -67,9 +65,9 @@ protected virtual bool IsErrorMetricEnabled

/// <summary>
/// Gets the PowerShell module name used for user agent header.
/// By default uses "Azurepowershell"
/// By default uses "AzureCLU"
/// </summary>
protected virtual string ModuleName { get { return "AzurePowershell"; } }
protected virtual string ModuleName { get { return "AzureCLU"; } }

/// <summary>
/// Gets PowerShell module version used for user agent header.
Expand Down Expand Up @@ -158,128 +156,21 @@ protected virtual void SetSessionVariable<T>(string name, T value) where T : cla
DataStore.WriteFile(variablePath, JsonConvert.SerializeObject(value));
}
}
/// <summary>
/// Initialize the data collection profile
/// </summary>
protected static void InitializeDataCollectionProfile()
{
if (_dataCollectionProfile != null && _dataCollectionProfile.EnableAzureDataCollection.HasValue)
{
return;
}

// Get the value of the environment variable for Azure PS data collection setting.
string value = Environment.GetEnvironmentVariable(AzurePSDataCollectionProfile.EnvironmentVariableName);
if (!string.IsNullOrWhiteSpace(value))
{
if (string.Equals(value, bool.FalseString, StringComparison.OrdinalIgnoreCase))
{
// Disable data collection only if it is explicitly set to 'false'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
}
else if (string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
// Enable data collection only if it is explicitly set to 'true'.
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
}
}

// If the environment value is null or empty, or not correctly set, try to read the setting from default file location.
if (_dataCollectionProfile == null)
{
string fileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
if (File.Exists(fileFullPath))
{
string contents = File.ReadAllText(fileFullPath);
_dataCollectionProfile = JsonConvert.DeserializeObject<AzurePSDataCollectionProfile>(contents);
}
}

// If the environment variable or file content is not set, create a new profile object.
if (_dataCollectionProfile == null)
{
_dataCollectionProfile = new AzurePSDataCollectionProfile();
}
}

/// <summary>
/// Get the data collection profile
/// </summary>
protected static AzurePSDataCollectionProfile GetDataCollectionProfile()
{
if (_dataCollectionProfile == null)
{
InitializeDataCollectionProfile();
}

return _dataCollectionProfile;
}

/// <summary>
/// Check whether the data collection is opted in from user
/// </summary>
/// <returns>true if allowed</returns>
public static bool IsDataCollectionAllowed()
protected abstract bool IsTelemetryCollectionEnabled
{
//TODO: CLU - remove before final release
return true;

//if (_dataCollectionProfile != null &&
// _dataCollectionProfile.EnableAzureDataCollection.HasValue &&
// _dataCollectionProfile.EnableAzureDataCollection.Value)
//{
// return true;
//}

//return false;
get;
}

/// <summary>
/// Save the current data collection profile Json data into the default file path
/// </summary>
protected abstract void SaveDataCollectionProfile();

protected bool CheckIfInteractive()
{
bool interactive = false;
//if (this.Host == null ||
// this.Host.UI == null ||
// this.Host.UI.RawUI == null ||
// Environment.GetCommandLineArgs().Any(s => s.Equals("-NonInteractive", StringComparison.OrdinalIgnoreCase)))
//{
// interactive = false;
//}
//else
//{
// try
// {
// var test = this.Host.UI.RawUI.KeyAvailable;
// }
// catch
// {
// interactive = false;
// }
//}

if (!interactive && !_dataCollectionProfile.EnableAzureDataCollection.HasValue)
{
_dataCollectionProfile.EnableAzureDataCollection = false;
}
return interactive;
}

/// <summary>
/// Prompt for the current data collection profile
/// </summary>
/// <param name="profile"></param>
protected abstract void PromptForDataCollectionProfileIfNotExists();

/// <summary>
/// Cmdlet begin process. Write to logs, setup Http Tracing and initialize profile
/// </summary>
protected override void BeginProcessing()
{
PromptForDataCollectionProfileIfNotExists();
InitializeQosEvent();
if (string.IsNullOrEmpty(ParameterSetName))
{
Expand Down Expand Up @@ -352,7 +243,7 @@ protected bool IsVerbose()

protected new void WriteError(ErrorRecord errorRecord)
{
FlushDebugMessages(IsDataCollectionAllowed());
FlushDebugMessages(IsTelemetryCollectionEnabled);
if (QosEvent != null && errorRecord != null)
{
QosEvent.Exception = errorRecord.Exception;
Expand Down Expand Up @@ -524,7 +415,7 @@ protected void LogQosEvent()
return;
}

if (!IsDataCollectionAllowed())
if (!IsTelemetryCollectionEnabled)
{
return;
}
Expand All @@ -533,8 +424,10 @@ protected void LogQosEvent()

try
{
MetricHelper.LogQoSEvent(QosEvent, IsUsageMetricEnabled, IsErrorMetricEnabled);
MetricHelper.FlushMetric();
MetricHelper.LogQoSEvent(QosEvent,
IsUsageMetricEnabled && IsTelemetryCollectionEnabled,
IsErrorMetricEnabled && IsTelemetryCollectionEnabled);
MetricHelper.FlushMetric(IsTelemetryCollectionEnabled);
WriteDebug("Finish sending metric.");
}
catch (Exception e)
Expand Down
39 changes: 0 additions & 39 deletions src/CLU/Commands.Common/AzurePSDataCollectionProfile.cs

This file was deleted.

16 changes: 3 additions & 13 deletions src/CLU/Commands.Common/MetricHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ public static void AddTelemetryClient(TelemetryClient client)

public static void LogQoSEvent(AzurePSQoSEvent qos, bool isUsageMetricEnabled, bool isErrorMetricEnabled)
{
if (!IsMetricTermAccepted())
{
return;
}

if (isUsageMetricEnabled)
{
LogUsageEvent(qos);
Expand Down Expand Up @@ -189,14 +184,9 @@ private static void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<s
}
}

public static bool IsMetricTermAccepted()
{
return AzurePSCmdlet.IsDataCollectionAllowed();
}

public static void FlushMetric()
public static void FlushMetric(bool isTelemetryEnabled)
{
if (!IsMetricTermAccepted())
if (!isTelemetryEnabled)
{
return;
}
Expand All @@ -205,7 +195,7 @@ public static void FlushMetric()
{
foreach (TelemetryClient client in TelemetryClients)
{
client.Flush();
Task.Run(() => client.Flush()).Wait(TimeSpan.FromSeconds(5));
}
}
catch
Expand Down
11 changes: 9 additions & 2 deletions src/CLU/Commands.Common/Models/PSAzureProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public static implicit operator PSAzureProfile(AzureRMProfile profile)

var result = new PSAzureProfile
{
Context = profile.Context
Context = profile.Context,
IsTelemetryCollectionEnabled = profile.IsTelemetryCollectionEnabled
};

profile.Environments
Expand All @@ -50,7 +51,8 @@ public static implicit operator AzureRMProfile(PSAzureProfile profile)

var result = new AzureRMProfile
{
Context = profile.Context
Context = profile.Context,
IsTelemetryCollectionEnabled = profile.IsTelemetryCollectionEnabled
};
profile.Environments.ForEach((e) => result.Environments[e.Key] = (AzureEnvironment) e.Value);
return result;
Expand All @@ -74,6 +76,11 @@ public string EnvironmentNames
/// </summary>
public PSAzureContext Context { get; set; }

/// <summary>
/// When set to true, collects telemetry information.
/// </summary>
public bool? IsTelemetryCollectionEnabled { get; set; }

public override string ToString()
{
return Context?.ToString();
Expand Down
Loading