public void EndOperation(TelemetryScope <OperationEvent> operation, TelemetryResult telemetryResult) { #if DEBUG _ = WriteTelemetryEventToOutputWindowAsync(operation.EndEvent, "Ended Operation"); #endif operation.End(telemetryResult); }
public void EndUserTask(TelemetryScope <UserTaskEvent> userTask, TelemetryResult telemetryResult) { #if DEBUG _ = WriteTelemetryEventToOutputWindowAsync(userTask.EndEvent, "Ended User Task"); #endif userTask.End(telemetryResult); }
protected TelemetryScopeBase(OperationEvent operationEvent, TelemetryIdentifier telemetryIdentifier, ITelemetryRecorder telemetryRecorder) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) result = (TelemetryResult)0; TelemetryEvent = (telemetryIdentifier ?? throw new ArgumentNullException("telemetryIdentifier")); TelemetryRecorder = (telemetryRecorder ?? throw new ArgumentNullException("telemetryRecorder")); endEvent = new VSTelemetryEvent(operationEvent); rootScope = this; }
/// <summary> /// Marks the end of this work and post end event. /// </summary> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> public void End(TelemetryResult result, string resultSummary = null) { if (Interlocked.CompareExchange(ref isEnded, 1, 0) == 1) { throw new InvalidOperationException("The scoped user task is already ended."); } EndEvent.SetResultProperties(result, resultSummary); EndEvent.SetTimeProperties(StartTime, DateTime.UtcNow, (DateTime.UtcNow - StartTime).TotalMilliseconds); TelemetrySession.PostEvent(EndEvent); }
public void PostUserTask(TelemetryIdentifier telemetryIdentifier, TelemetryResult result) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (telemetryIdentifier == null) { throw new ArgumentNullException("telemetryIdentifier"); } telemetryRecorder.RecordEvent((TelemetryEvent)(object)new UserTaskEvent(telemetryIdentifier.Value, result, (string)null)); }
public static void TrackOperation(string name, TelemetryResult result = TelemetryResult.None, params KeyValuePair <string, object>[] properties) { string actualName = name.Replace(" ", "_"); var task = new OperationEvent(Namespace + actualName, result); foreach (KeyValuePair <string, object> property in properties) { task.Properties.Add(property); } TelemetryService.DefaultSession.PostEvent(task); }
private async void ExecuteAsync(object sender, EventArgs e) { ProjectItem configProjectItem = VsHelpers.DTE.SelectedItems.Item(1).ProjectItem; if (configProjectItem != null) { await LibraryHelpers.CleanAsync(configProjectItem); } TelemetryResult result = configProjectItem != null ? TelemetryResult.Success : TelemetryResult.Failure; Telemetry.TrackUserTask("clean", result); }
public TelemetryEventCorrelation PostOperation(string eventName, TelemetryResult result, string resultSummary = null, TelemetryEventCorrelation[] correlatedWith = null) { Requires.NotNullOrEmpty(eventName, nameof(eventName)); if (result == TelemetryResult.None) { throw new ArgumentException(null, nameof(result)); } return(TelemetryService.DefaultSession.PostOperation( eventName: eventName, result: result, resultSummary: resultSummary, correlatedWith: correlatedWith)); }
public void PostUserTask(TelemetryIdentifier telemetryIdentifier, TelemetryResult result, IEnumerable <DataPoint> properties) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (telemetryIdentifier == null) { throw new ArgumentNullException("telemetryIdentifier"); } UserTaskEvent val = (UserTaskEvent)(object)new UserTaskEvent(telemetryIdentifier.Value, result, (string)null); DataPointCollection.AddCollectionToDictionary(properties, ((TelemetryEvent)val).Properties); telemetryRecorder.RecordEvent((TelemetryEvent)(object)val); }
public void PostOperation(TelemetryIdentifier telemetryIdentifier, TelemetryResult result) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (telemetryIdentifier == null) { throw new ArgumentNullException("telemetryIdentifier"); } OperationEvent val = (OperationEvent)(object)new OperationEvent(telemetryIdentifier.Value, result, (string)null); EndEvent.Correlate(((TelemetryEvent)val).Correlation); TelemetryRecorder.RecordEvent((TelemetryEvent)(object)val); }
public static async Task CleanAsync(ProjectItem configProjectItem) { Logger.LogEvent(Resources.Text.CleanLibrariesStarted, LogLevel.Task); string configFileName = configProjectItem.FileNames[1]; var dependencies = Dependencies.FromConfigFile(configFileName); Manifest manifest = await Manifest.FromFileAsync(configFileName, dependencies, CancellationToken.None).ConfigureAwait(false); var hostInteraction = dependencies.GetHostInteractions() as HostInteraction; int?filesDeleted = manifest?.Clean((file) => hostInteraction.DeleteFiles(file)); Logger.LogEvent(Resources.Text.CleanLibrariesSucceeded + Environment.NewLine, LogLevel.Task); TelemetryResult result = configProjectItem != null ? TelemetryResult.Success : TelemetryResult.Failure; Telemetry.TrackUserTask("clean", new KeyValuePair <string, object>("filesdeleted", filesDeleted)); }
/// <summary> /// Create an operation event with specified information. /// </summary> /// <param name="eventName"> /// An event name following data model schema. /// It requires that event name is a unique, not null or empty string. /// It consists of 3 parts and must follows pattern [product]/[featureName]/[entityName]. FeatureName could be a one-level feature or feature hierarchy delimited by "/". /// For examples, /// vs/platform/opensolution; /// vs/platform/editor/lightbulb/fixerror; /// </param> /// <param name="stageType">operation stage type.</param> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> internal OperationEvent(string eventName, OperationStageType stageType, TelemetryResult result, string resultSummary = null) : this(eventName, DataModelEventType.Operation, stageType, result, resultSummary) { }
/// <summary> /// Initializes a new instance of the <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> class. /// </summary> /// <param name="eventName"> /// An event name following data model schema. /// It requires that event name is a unique, not null or empty string. /// It consists of 3 parts and must follows pattern [product]/[featureName]/[entityName]. FeatureName could be a one-level feature or feature hierarchy delimited by "/". /// For examples, /// vs/platform/opensolution; /// vs/platform/editor/lightbulb/fixerror; /// </param> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> /// <example> /// This example shows how to create and post <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" />. /// <code> /// OperationEvent operation = new OperationEvent("vs/debugger/loadingAssembly", Result.Success); /// TelemetryService.DefaultSession.PostEvent(operation); /// </code> /// </example> public OperationEvent(string eventName, TelemetryResult result, string resultSummary = null) : this(eventName, OperationStageType.Atomic, result, resultSummary) { }
void ILoggingServiceInternal.PostEvent(DataModelEventType eventType, string eventName, TelemetryResult result, params (string name, object property)[] namesAndProperties)
public void PostEvent(TelemetryEventType eventType, string eventName, TelemetryResult result, IReadOnlyList <(string name, object property)> namesAndProperties)
/// <summary> /// Initializes a new instance of the <see cref="T:Coding4Fun.VisualStudio.Telemetry.UserTaskEvent" /> class. /// </summary> /// <param name="eventName"> /// An event name following data model schema. /// It requires that event name is a unique, not null or empty string. /// It consists of 3 parts and must follows pattern [product]/[featureName]/[entityName]. FeatureName could be a one-level feature or feature hierarchy delimited by "/". /// For examples, /// vs/platform/opensolution; /// vs/platform/editor/lightbulb/fixerror; /// </param> /// <param name="stageType">The stage of User Task.</param> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> internal UserTaskEvent(string eventName, OperationStageType stageType, TelemetryResult result, string resultSummary = null) : base(eventName, DataModelEventType.UserTask, stageType, result, resultSummary) { base.Severity = TelemetrySeverity.High; }
/// <summary> /// Function called after a project file change has been detected which pushes the changes to CPS. The return value indicates the status of the /// reload. /// </summary> public async Task <ProjectReloadResult> ReloadProjectAsync() { // We need a write lock to modify the project file contents. Note that all awaits while holding the lock need // to capture the context as the project lock service has a special execution context which ensures only a single // thread has access. using (var writeAccess = await _projectVsServices.ProjectLockService.WriteLockAsync()) { await writeAccess.CheckoutAsync(_projectVsServices.Project.FullPath).ConfigureAwait(true); var msbuildProject = await writeAccess.GetProjectXmlAsync(_projectVsServices.Project.FullPath, CancellationToken.None).ConfigureAwait(true); TelemetryResult operationResult = (TelemetryResult)(-1); string resultSummary = null; Exception exception = null; try { if (msbuildProject.HasUnsavedChanges) { // For now force a solution reload. operationResult = TelemetryResult.Failure; resultSummary = "Project Dirty"; return(ProjectReloadResult.ReloadFailedProjectDirty); } else { try { var oldProjectProperties = msbuildProject.Properties.ToImmutableArray(); // This reloads the project off disk and handles if the new XML is invalid msbuildProject.Reload(); // Handle project reload interception. if (ProjectReloadInterceptors.Count > 0) { var newProjectProperties = msbuildProject.Properties.ToImmutableArray(); foreach (var projectReloadInterceptor in ProjectReloadInterceptors) { var reloadResult = projectReloadInterceptor.Value.InterceptProjectReload(oldProjectProperties, newProjectProperties); if (reloadResult != ProjectReloadResult.NoAction) { operationResult = TelemetryResult.Failure; resultSummary = "Reload interceptor rejected reload"; return(reloadResult); } } } // There isn't a way to clear the dirty flag on the project xml, so to work around that the project is saved // to a StringWriter. var tw = new StringWriter(); msbuildProject.Save(tw); operationResult = TelemetryResult.Success; resultSummary = null; } catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex) { // Indicate we weren't able to complete the action. We want to do a normal reload exception = ex; operationResult = TelemetryResult.Failure; resultSummary = "Project Reload Failure due to invalid project file"; return(ProjectReloadResult.ReloadFailed); } catch (Exception ex) { // Any other exception likely mean the msbuildProject is not in a good state. Example, DeepCopyFrom failed. // The only safe thing to do at this point is to reload the project in the solution // TODO: should we have an additional return value here to indicate that the existing project could be in a bad // state and the reload needs to happen without the user being able to block it? operationResult = TelemetryResult.Failure; resultSummary = "Project Reload Failure due to general fault"; exception = ex; System.Diagnostics.Debug.Assert(false, "Replace xml failed with: " + ex.Message); return(ProjectReloadResult.ReloadFailed); } } } finally { Contract.Requires((int)operationResult != -1); TelemetryEventCorrelation[] correlations = null; if (exception != null) { var correlation = _telemetryService.Report(TelemetryEvents.ReloadFailedNFWPath, resultSummary, exception); correlations = new[] { correlation }; } _telemetryService.PostOperation(TelemetryEvents.ReloadResultOperationPath, operationResult, resultSummary, correlations); } } // It is important to wait for the new tree to be published to ensure all updates have occurred before the reload manager // releases its hold on the UI thread. This prevents unnecessary race conditions and prevent the user // from interacting with the project until the evaluation has completed. await _projectVsServices.ProjectTree.TreeService.PublishLatestTreeAsync(blockDuringLoadingTree : true).ConfigureAwait(false); return(ProjectReloadResult.ReloadCompleted); }
public void EndTelemetryScope(object telemetryScope, TelemetryResult result, string summary = null) { }
/// <summary> /// Initializes a new instance of the <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> class. /// </summary> /// <param name="eventName"> /// An event name following data model schema. /// It requires that event name is a unique, not null or empty string. /// It consists of 3 parts and must follows pattern [product]/[featureName]/[entityName]. FeatureName could be a one-level feature or feature hierarchy delimited by "/". /// For examples, /// vs/platform/opensolution; /// vs/platform/editor/lightbulb/fixerror; /// </param> /// <param name="eventType">The type of event.</param> /// <param name="stageType">The type of operation.</param> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> internal OperationEvent(string eventName, DataModelEventType eventType, OperationStageType stageType, TelemetryResult result, string resultSummary = null) : base(eventName, TelemetrySeverity.Normal, eventType) { if (eventType != 0 && eventType != DataModelEventType.Operation) { throw new ArgumentException("Expect DataModelEventType UserTask or Operation only.", "eventType"); } DataModelEventNameHelper.SetProductFeatureEntityName(this); StageType = stageType; SetResultProperties(result, resultSummary); }
/// <summary> /// Post an Operation event. /// An operation performs some work in application and comes with result (e.g., Success, Failure). /// If the operation is invoked by user directly, please use <see cref="T:Coding4Fun.VisualStudio.Telemetry.UserTaskEvent" /> or related methods. /// A few examples of operations are, license check, package load, windows layout loading. /// /// This method is used for atomic operation that runs very fast or has little value to analyze the process duration. Caller calls this method when operation is complete. /// For long-time running or async operation, in order to understand what else happened during the time or track if it partially completes because of an error, /// use method <see cref="M:Coding4Fun.VisualStudio.Telemetry.TelemetrySessionExtensions.StartOperation(Coding4Fun.VisualStudio.Telemetry.TelemetrySession,System.String)" /> which tracks both start and end points. /// </summary> /// <param name="session">telemetry session object.</param> /// <param name="eventName"> /// An event name following data model schema. /// It requires that event name is a unique, not null or empty string. /// It consists of 3 parts and must follows pattern [product]/[featureName]/[entityName]. FeatureName could be a one-level feature or feature hierarchy delimited by "/". /// For examples, /// vs/platform/opensolution; /// vs/platform/editor/lightbulb/fixerror; /// </param> /// <param name="result">the result of this user task. If the result is Failure, recommend correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />.</param> /// <param name="resultSummary"> /// optional parameter. a summary description for the result. /// it provides a little bit more details about the result without digging into it. /// when correlated with fault event, use this parameter to summarize the additional information stored in <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" />. /// E.g., "sign in failed because of wrong credential", "user cancelled azure deployment". /// Default value is null. /// </param> /// <param name="correlatedWith"> /// Specify which events to correlate by using property <see cref="P:Coding4Fun.VisualStudio.Telemetry.TelemetryEvent.Correlation" /> /// Good candidates to correlate with <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> are, /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.FaultEvent" /> /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.AssetEvent" /> /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.UserTaskEvent" /> /// </param> /// <returns>The operation event correlation.</returns> public static TelemetryEventCorrelation PostOperation(this TelemetrySession session, string eventName, TelemetryResult result, string resultSummary = null, TelemetryEventCorrelation[] correlatedWith = null) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(session, "session"); return(session.PostOperationHelper(() => new OperationEvent(eventName, result, resultSummary), correlatedWith)); }
/// <summary> /// Set result related properties /// </summary> /// <param name="result">the result of this operation</param> /// <param name="resultSummary">a summary description for the result. Default value is null.</param> internal void SetResultProperties(TelemetryResult result, string resultSummary) { Result = result; ResultSummary = resultSummary; }
protected async virtual Task <TelemetryResult> RunWithTelemetryAsync( int totalOfExecutions, bool runInParallel, Func <int, Task <bool> > handler, int maxTestExecutionTimeInSeconds = 60, Func <TelemetryResult, Task <bool> > customSuccessCriteriaFunction = null, [CallerMemberName] string identifier = null) { var telemetryResult = new TelemetryResult(identifier, totalOfExecutions); var completedExecutions = 0; var globalStopwatch = new Stopwatch(); if (runInParallel) { var allDone = new ManualResetEvent(initialState: false); globalStopwatch.Start(); for (int i = 0; i < totalOfExecutions; i++) { ThreadPool.QueueUserWorkItem(async _ => { telemetryResult.AddTestExecution(await new TestExecution(handler).Execute(completedExecutions).ConfigureAwait(false)); Interlocked.Increment(ref completedExecutions); if (completedExecutions >= totalOfExecutions) { allDone.Set(); } }); } allDone.WaitOne(TimeSpan.FromSeconds(maxTestExecutionTimeInSeconds)); globalStopwatch.Stop(); allDone.Set(); } else { globalStopwatch.Start(); for (int i = 0; i < totalOfExecutions; i++) { telemetryResult.AddTestExecution(await new TestExecution(handler).Execute(i).ConfigureAwait(false)); } globalStopwatch.Stop(); completedExecutions = totalOfExecutions; } telemetryResult.SetTelemetryResultProcess( telemetryResult: await telemetryResult.ProcessResultAsync(customSuccessCriteriaFunction).ConfigureAwait(false), totalOfExecutions: totalOfExecutions, completedExecutions: completedExecutions ); WriteTelemetryResult( telemetryResult, globalStopwatch.ElapsedMilliseconds, totalOfExecutions, completedExecutions, runInParallel, maxTestExecutionTimeInSeconds, customSuccessCriteriaFunction != null, identifier); Assert.True(telemetryResult.Success); return(telemetryResult); }
public void PostEvent(TelemetryEventType eventType, string eventName, TelemetryResult result = TelemetryResult.Success, params (string name, object property)[] namesAndProperties)
private void WriteTelemetryResult( TelemetryResult telemetryResult, long elapsedMilliseconds, int totalOfExecutions, int completedExecutions, bool runInParallel, int maxTestExecutionTimeInSeconds, bool haveCustomSuccessCriteriaFunction, string identifier) { var emptyLineText = "-"; WriteLog($"Test: {identifier}"); WriteLog($"Process Date: {telemetryResult.ProcessDate}"); WriteLog($"Result: {(telemetryResult.Success ? "SUCCESS" : "FAIL")}"); WriteLog($"Executions Duration: {TimeSpan.FromMilliseconds(elapsedMilliseconds)}"); WriteLog($"Total of Executions: {totalOfExecutions}"); WriteLog($"Completed Executions: {completedExecutions}"); WriteLog($"Run in Parallel: {runInParallel}"); WriteLog($"Max Test Execution Time: {TimeSpan.FromSeconds(maxTestExecutionTimeInSeconds)}"); WriteLog($"Have Custom Success Criteria: {haveCustomSuccessCriteriaFunction}"); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog("MEDIAN"); WriteTestExecution( telemetryResult.MedianTelemetryInfo.Gen0, telemetryResult.MedianTelemetryInfo.Gen1, telemetryResult.MedianTelemetryInfo.Gen2, telemetryResult.MedianTelemetryInfo.CPUUsage, telemetryResult.MedianTelemetryInfo.TotalOfMemoryKb, telemetryResult.MedianTelemetryInfo.ExecutionTime); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog("MAX"); WriteTestExecution( telemetryResult.MaxTelemetryInfo.Gen0, telemetryResult.MaxTelemetryInfo.Gen1, telemetryResult.MaxTelemetryInfo.Gen2, telemetryResult.MaxTelemetryInfo.CPUUsage, telemetryResult.MaxTelemetryInfo.TotalOfMemoryKb, telemetryResult.MaxTelemetryInfo.ExecutionTime); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog("MIN"); WriteTestExecution( telemetryResult.MinTelemetryInfo.Gen0, telemetryResult.MinTelemetryInfo.Gen1, telemetryResult.MinTelemetryInfo.Gen2, telemetryResult.MinTelemetryInfo.CPUUsage, telemetryResult.MinTelemetryInfo.TotalOfMemoryKb, telemetryResult.MinTelemetryInfo.ExecutionTime); for (int i = totalOfExecutions > 10 ? 10 : totalOfExecutions; i > 0; i--) { WriteLog(emptyLineText); WriteLog(emptyLineText); WriteLog(emptyLineText); WriteTestExecution(telemetryResult.TestExectionCollection.ToList()[telemetryResult.TestExectionCollection.Count - i]); } Assert.True(telemetryResult.Success); }
public static void TrackOperation(string name, TelemetryResult result = TelemetryResult.Success) { string actualName = name.Replace(" ", "_"); TelemetryService.DefaultSession.PostOperation(_namespace + actualName, result); }
/// <summary> /// Get Telemetry Result string used in backend. /// PLEASE DO NOT change the logic. Enum name is part of contract between client and backend server. /// </summary> /// <param name="result"></param> /// <returns></returns> internal static string GetString(TelemetryResult result) { return(result.ToString()); }