private async Task Check(BehaviorOnStale staleBehavior, CancellationToken token = default(CancellationToken)) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) try { await LoadManifest(staleBehavior, token).ConfigureAwait(false); } catch (TelemetryManifestParserException ex) { if (!token.IsCancellationRequested) { List <string> list = new List <string>(); for (Exception innerException = ex.InnerException; innerException != null; innerException = innerException.InnerException) { list.Add(innerException.Message); } OnUpdateTelemetryManifestStatusEvent(new TelemetryManifestEventArgs(null)); InstrumentLoad(null, 0L, ex.Message, (list.Count > 0) ? StringExtensions.Join((IEnumerable <string>)list, ";") : null, 0.0); } } catch (Exception exceptionObject) { FaultEvent faultEvent = new FaultEvent("VS/Telemetry/InternalFault", $"LoadManifest ManifestManager.Check", exceptionObject) { PostThisEventToTelemetry = false }; faultEvent.AddProcessDump(Process.GetCurrentProcess().Id); mainSession.PostEvent(faultEvent); } }
private void Reset(TelemetrySession mainSession, TelemetryManifest newManifest, DateTimeOffset timeToReset) { if (mainSession != null && (counter > threshold || whitelistCounter > threshold)) { string value = "Unknown"; TelemetryManifest currentManifest = mainSession.EventProcessor.CurrentManifest; if (currentManifest != null) { value = currentManifest.Version; } Dictionary <string, object> dictionary = new Dictionary <string, object>(); dictionary["VS.TelemetryApi.DynamicTelemetry.Manifest.Version"] = value; dictionary["VS.TelemetryApi.DynamicTelemetry.HostName"] = mainSession.HostName; dictionary["VS.TelemetryApi.ClientSideThrottling.Threshold"] = threshold; dictionary["VS.TelemetryApi.ClientSideThrottling.TimerReset"] = resetCounter; dictionary["VS.TelemetryApi.ClientSideThrottling.BucketStart"] = bucketStartTime.UtcDateTime.ToString("MM/dd/yy H:mm:ss.fffffff", CultureInfo.InvariantCulture); if (counter > threshold) { long num = counter - threshold; TelemetryEvent telemetryEvent = new TelemetryEvent("VS/TelemetryApi/ClientSideThrottling"); DictionaryExtensions.AddRange <string, object>(telemetryEvent.Properties, (IDictionary <string, object>)dictionary, true); telemetryEvent.Properties["VS.TelemetryApi.ClientSideThrottling.TotalDropped"] = num; telemetryEvent.Properties["VS.TelemetryApi.ClientSideThrottling.Events"] = StringExtensions.Join((IEnumerable <string>)droppedEvents, ","); mainSession.PostEvent(telemetryEvent); } if (whitelistCounter > threshold) { long num2 = whitelistCounter - threshold; TelemetryEvent telemetryEvent2 = new TelemetryEvent("VS/TelemetryApi/ClientSideThrottling/NoisyWhitelist"); DictionaryExtensions.AddRange <string, object>(telemetryEvent2.Properties, (IDictionary <string, object>)dictionary, true); telemetryEvent2.Properties["VS.TelemetryApi.ClientSideThrottling.TotalNoise"] = num2; telemetryEvent2.Properties["VS.TelemetryApi.ClientSideThrottling.Events"] = StringExtensions.Join((IEnumerable <string>)noisyWhiteListEvents, ","); mainSession.PostEvent(telemetryEvent2); } } counter = 0L; whitelistCounter = 0L; bucketStartTime = timeToReset; if (newManifest != null) { if (newManifest.ThrottlingThreshold > 0) { threshold = newManifest.ThrottlingThreshold; } if (newManifest.ThrottlingTimerReset > 0.0) { resetCounter = newManifest.ThrottlingTimerReset; } } droppedEvents.Clear(); noisyWhiteListEvents.Clear(); }
private void CollectAndSendIdentityEvaluationValuesEvent(TelemetrySession telemetrySession, CancellationToken cancellationToken) { try { KeyValuePair <string, object>[] array = GetIdentityProperties(cancellationToken).ToArray(); if (!SendIdentityValuesEvent) { return; } TelemetryEvent telemetryEvent = new TelemetryEvent("VS/TelemetryApi/Identity/EvaluationValues"); KeyValuePair <string, object>[] array2 = array; for (int i = 0; i < array2.Length; i++) { KeyValuePair <string, object> keyValuePair = array2[i]; telemetryEvent.Properties.Add(keyValuePair.Key, keyValuePair.Value); } cancellationToken.ThrowIfCancellationRequested(); telemetrySession.PostEvent(telemetryEvent); } catch (OperationCanceledException) { throw; } catch (Exception exceptionObject) { telemetrySession.PostFault(EvaluationValuesEventFaultName, "SendIdentityEvaluationValuesEvent", exceptionObject); } foreach (KeyValuePair <string, Exception> exception in exceptions) { telemetrySession.PostFault(EvaluationValuesEventFaultName, exception.Key, exception.Value); } }
private static TelemetryEventCorrelation PostOperationHelper <T>(this TelemetrySession session, Func <T> createEvent, TelemetryEventCorrelation[] correlatedWith) where T : OperationEvent { T val = createEvent(); val.Correlate(correlatedWith); session.PostEvent(val); return(val.Correlation); }
/// <summary> /// Post a fault event with an exception object and a callback. The callback can be used to calculate expensive data to be sent /// to the Watson back end, such as JScript callstacks, etc /// It becomes more useful when correlated with <see cref="T:Coding4Fun.VisualStudio.Telemetry.UserTaskEvent" /> or <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> which may have led to the fault occurence. /// </summary> /// <param name="telemetrySession"></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="description"></param> /// <param name="faultSeverity">The severity of the fault, used to identify actionable or important faults in divisional tools and reporting.</param> /// <param name="exceptionObject">can be null</param> /// <param name="gatherEventDetails">Allows the user to provide code to execute synchronously to gather computationally expensive info about the event</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.FaultEvent" /> are, /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.UserTaskEvent" /> /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> /// </param> /// <returns>The fault correlation.</returns> public static TelemetryEventCorrelation PostFault(this TelemetrySession telemetrySession, string eventName, string description, FaultSeverity faultSeverity, Exception exceptionObject, Func <IFaultUtility, int> gatherEventDetails, TelemetryEventCorrelation[] correlatedWith) { FaultEvent faultEvent = new FaultEvent(eventName, description, faultSeverity, exceptionObject, gatherEventDetails); faultEvent.Correlate(correlatedWith); telemetrySession.PostEvent(faultEvent); return(faultEvent.Correlation); }
/// <summary> /// Post an Asset event. /// Asset is the target of user task or operation, e.g., Solution, Project, File, Extension, License, Designer. /// </summary> /// <param name="telemetrySession">Telemetry Session</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="assetId"> /// Used to identify the asset. The id should be immutable in the asset life cycle, even if the status or content changes over time. /// E.g., project guid is generated during project creation and will never change. This makes it a good candidate for asset id of Project asset. /// </param> /// <param name="assetEventVersion"> /// Used for customized properties versioning. /// E.g., project asset posts event with name "vs/platform/project". /// If the event is updated, uses this parameter to increment the version. /// </param> /// <param name="properties">customized properties for this asset event.</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.AssetEvent" /> are, /// <see cref="T:Coding4Fun.VisualStudio.Telemetry.AssetEvent" /> (to build up asset hierarchy/extension.) /// </param> /// <returns>The asset event correlation.</returns> public static TelemetryEventCorrelation PostAsset(this TelemetrySession telemetrySession, string eventName, string assetId, int assetEventVersion, IDictionary <string, object> properties, TelemetryEventCorrelation[] correlatedWith = null) { CodeContract.RequiresArgumentNotNull <IDictionary <string, object> >(properties, "properties"); AssetEvent assetEvent = new AssetEvent(eventName, assetId, assetEventVersion); DictionaryExtensions.AddRange <string, object>(assetEvent.Properties, properties, true); assetEvent.Correlate(correlatedWith); telemetrySession.PostEvent(assetEvent); return(assetEvent.Correlation); }
/// <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 PostDiagnosticInformation(TelemetrySession mainSession, TelemetryManifest newManifest) { if (totalPropertyCount != 0) { string value = "Unknown"; TelemetryManifest currentManifest = mainSession.EventProcessor.CurrentManifest; if (currentManifest != null) { value = currentManifest.Version; } TelemetryEvent telemetryEvent = new TelemetryEvent("VS/TelemetryApi/" + DiagnosticName); telemetryEvent.Properties["VS.TelemetryApi.DynamicTelemetry.Manifest.Version"] = value; telemetryEvent.Properties["VS.TelemetryApi.DynamicTelemetry.HostName"] = mainSession.HostName; telemetryEvent.Properties["VS.TelemetryApi." + DiagnosticName + ".TotalCount"] = totalPropertyCount; telemetryEvent.Properties["VS.TelemetryApi." + DiagnosticName + ".Properties"] = StringExtensions.Join(properties.Select((string x) => x.ToLower(CultureInfo.InvariantCulture)), ","); mainSession.PostEvent(telemetryEvent); } }
public TelemetryManifestManager(IRemoteControlClient theRemoteControlClient, ITelemetryManifestManagerSettings theSettings, ITelemetryManifestParser theManifestParser, ITelemetryScheduler theScheduler, TelemetrySession theMainSession) { CodeContract.RequiresArgumentNotNull <ITelemetryManifestParser>(theManifestParser, "theManifestParser"); CodeContract.RequiresArgumentNotNull <ITelemetryScheduler>(theScheduler, "theScheduler"); CodeContract.RequiresArgumentNotNull <TelemetrySession>(theMainSession, "theMainSession"); manifestParser = theManifestParser; scheduler = theScheduler; scheduler.InitializeTimed(ReadInterval); mainSession = theMainSession; remoteControlClient = theRemoteControlClient; settings = theSettings; RemoteControlClient.TelemetryLogger2 = ((Action <string, IDictionary <string, object>, IDictionary <string, object> >) delegate(string eventName, IDictionary <string, object> properties, IDictionary <string, object> piiProperties) { TelemetryEvent telemetryEvent = new TelemetryEvent(eventName); DictionaryExtensions.AddRange <string, object>(telemetryEvent.Properties, properties, true); DictionaryExtensions.AddRange <string, object>(telemetryEvent.Properties, (IDictionary <string, object>)((IEnumerable <KeyValuePair <string, object> >)piiProperties).ToDictionary((Func <KeyValuePair <string, object>, string>)((KeyValuePair <string, object> p) => p.Key), (Func <KeyValuePair <string, object>, object>)((KeyValuePair <string, object> p) => new TelemetryPiiProperty(p.Value))), true); mainSession.PostEvent(telemetryEvent); }); }
/// <summary> /// Queues a telemetry event with command line flags information with additional properties to be posted to the server. /// Only command line flags (identified by the given prefixes) will be included. /// </summary> /// <param name="session">A <see cref="T:Coding4Fun.VisualStudio.Telemetry.TelemetrySession" /> to post the event with.</param> /// <param name="flagPrefixes">The prefix(s) to identify a program's flag.</param> /// <param name="additionalProperties">Optional additional properties to include with the event.</param> /// <exception cref="T:System.ArgumentNullException">If session is null.</exception> /// <exception cref="T:System.ArgumentException">If eventName is null, empty or white space.</exception> /// <exception cref="T:System.ArgumentException"> /// If no prefixes are specified, or all prefixes are null, empty or white space. /// </exception> public static void PostCommandLineFlags(this TelemetrySession session, IEnumerable <string> flagPrefixes, IDictionary <string, object> additionalProperties) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(session, "session"); CommandLineFlagsInfo commandLineFlagsInfo = ComputeCommandLineFlags(flagPrefixes); TelemetryEvent telemetryEvent = new TelemetryEvent("vs/telemetryapi/commandlineflags"); telemetryEvent.Properties["VS.TelemetryApi.CommandLineFlags.ArgsCount"] = commandLineFlagsInfo.ArgsCount; telemetryEvent.Properties["VS.TelemetryApi.CommandLineFlags.FlagsCount"] = commandLineFlagsInfo.Flags.Length; telemetryEvent.Properties["VS.TelemetryApi.CommandLineFlags.FirstFlag"] = ((commandLineFlagsInfo.Flags.Length != 0) ? commandLineFlagsInfo.Flags[0] : string.Empty); telemetryEvent.Properties["VS.TelemetryApi.CommandLineFlags.Flags"] = new TelemetryComplexProperty(commandLineFlagsInfo.Flags); if (additionalProperties != null) { foreach (KeyValuePair <string, object> additionalProperty in additionalProperties) { telemetryEvent.Properties[additionalProperty.Key] = additionalProperty.Value; } } session.PostEvent(telemetryEvent); }
/// <summary> /// Post diagnostic telemetry. Generates events with properties and send them. /// </summary> /// <param name="telemetrySession"></param> /// <param name="propertyBag"></param> public void PostDiagnosticTelemetryWhenSessionInitialized(TelemetrySession telemetrySession, IEnumerable <KeyValuePair <string, object> > propertyBag) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(telemetrySession, "telemetrySession"); CodeContract.RequiresArgumentNotNull <IEnumerable <KeyValuePair <string, object> > >(propertyBag, "propertyBag"); if (!telemetrySession.IsSessionCloned) { TelemetryEvent telemetryEvent = new TelemetryEvent("VS/TelemetryApi/Session/Initialized"); if (registrySettings.Count > 0) { foreach (KeyValuePair <string, string> registrySetting in registrySettings) { telemetryEvent.Properties[registrySetting.Key] = registrySetting.Value; } } foreach (KeyValuePair <string, object> item in propertyBag) { telemetryEvent.Properties[item.Key] = item.Value; } telemetrySession.PostEvent(telemetryEvent); } }
/// <summary> /// Create and post an event for start point, and then create a user event for end point (but not posted.) /// </summary> /// <param name="telemetrySession">Telemetry Session</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="createNewEvent">A function to create a new event.</param> /// <param name="settings">A <see cref="T:Coding4Fun.VisualStudio.Telemetry.TelemetryScopeSettings" /> object to control the TelemetryScope behavior.</param> /// <remarks> /// Because the same event name is used by both start and end events, please don't use Start or End in event name. /// </remarks> internal TelemetryScope(TelemetrySession telemetrySession, string eventName, CreateNewEvent createNewEvent, TelemetryScopeSettings settings) { isEnded = 0; TelemetrySession = telemetrySession; Guid.NewGuid(); StartTime = DateTime.UtcNow; T val = createNewEvent(OperationStageType.Start); val.Severity = settings.Severity; val.Correlate(settings.Correlations); val.IsOptOutFriendly = settings.IsOptOutFriendly; if (settings.StartEventProperties != null) { DictionaryExtensions.AddRange <string, object>(val.Properties, settings.StartEventProperties, true); } if (settings.PostStartEvent) { TelemetrySession.PostEvent(val); } EndEvent = val; EndEvent.SetPostStartEventProperty(settings.PostStartEvent); EndEvent.StageType = OperationStageType.End; }