internal void FlushPostedProperties() { RequiresNotDisposed(); if (postedProperties.Count == 0 || !scheduler.CanEnterTimedDelegate()) { return; } TelemetryEvent telemetryEvent = CreateTelemetryEvent("PostProperty"); PostPropertyEntry result; while (postedProperties.TryDequeue(out result)) { if (result.IsReserved) { telemetryEvent.ReservedProperties[result.Key] = result.Value; } else { telemetryEvent.Properties[result.Key] = result.Value; } } TelemetrySession.ValidateEvent(telemetryEvent); ValidateEventProperties(telemetryEvent); AddReservedPropertiesToTheEvent(telemetryEvent); hostSession.PostValidatedEvent(telemetryEvent); scheduler.ExitTimedDelegate(); }
/// <summary> /// Create new default session with specified parameters /// </summary> /// <param name="appInsightsIKey"></param> /// <param name="asimovIKey"></param> /// <returns></returns> public static TelemetrySession CreateAndGetDefaultSession(string appInsightsIKey, string asimovIKey) { bool flag = true; if (InternalDefaultSession == null) { lock (lockDefaultSessionCreation) { if (InternalDefaultSession == null) { CodeContract.RequiresArgumentNotEmptyOrWhitespace(appInsightsIKey, "appInsightsIKey"); CodeContract.RequiresArgumentNotEmptyOrWhitespace(asimovIKey, "asimovIKey"); TelemetrySessionInitializer @default = TelemetrySessionInitializer.Default; @default.AppInsightsInstrumentationKey = appInsightsIKey; @default.AsimovInstrumentationKey = asimovIKey; InternalDefaultSession = TelemetrySession.Create(@default); flag = false; } } } if (flag) { throw new InvalidOperationException("Unable to create new default Telemetry Session with provided keys."); } return(InternalDefaultSession); }
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); } }
public EventProcessorContext(TelemetrySession hostTelemetrySession, IEventProcessorRouter eventProcessorRouter) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(hostTelemetrySession, "hostTelemetrySession"); CodeContract.RequiresArgumentNotNull <IEventProcessorRouter>(eventProcessorRouter, "eventProcessorRouter"); this.hostTelemetrySession = hostTelemetrySession; this.eventProcessorRouter = eventProcessorRouter; }
/// <summary> /// Execute action on event, using eventProcessorContext as a provider of the necessary information. /// Return true if it is allowed to execute next actions. /// Return false action forbids the event. /// /// Please note that although we are throttling, the reset actually occurs when the following event /// is processed. This means if we sent 1k events under a second, and do not do anything for 10 minutes /// and then send an event, the Reset will occur then. This was done to simplify code as this feature /// is primarily for events under development. /// </summary> /// <param name="eventProcessorContext"></param> /// <returns>Indicator, whether current action is not explicitely forbid current event</returns> public bool Execute(IEventProcessorContext eventProcessorContext) { CodeContract.RequiresArgumentNotNull <IEventProcessorContext>(eventProcessorContext, "eventProcessorContext"); TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; DateTimeOffset postTimestamp = telemetryEvent.PostTimestamp; if (bucketStartTime == default(DateTimeOffset)) { bucketStartTime = postTimestamp; } if (eventProcessorContext.ThrottlingAction == ThrottlingAction.DoNotThrottle || (eventProcessorContext.ThrottlingAction != ThrottlingAction.Throttle && passthroughEvents.Contains(telemetryEvent.Name))) { if (counter < threshold) { counter++; } else if (whitelistCounter >= threshold) { noisyWhiteListEvents.Add(telemetryEvent.Name); } whitelistCounter++; return(true); } if ((postTimestamp - bucketStartTime).TotalSeconds > resetCounter) { TelemetrySession hostTelemetrySession = eventProcessorContext.HostTelemetrySession; Reset(hostTelemetrySession, hostTelemetrySession.EventProcessor.CurrentManifest, postTimestamp); } if (counter++ >= threshold) { droppedEvents.Add(telemetryEvent.Name); return(false); } return(true); }
/// <summary> /// Event processor constructor should be provided with session. /// This required for start channels. /// </summary> /// <param name="session"></param> /// <param name="eventProcessorContext"></param> public EventProcessor(TelemetrySession session, IEventProcessorContext eventProcessorContext) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(session, "session"); CodeContract.RequiresArgumentNotNull <IEventProcessorContext>(eventProcessorContext, "eventProcessorContext"); mainSession = session; this.eventProcessorContext = eventProcessorContext; }
/// <summary> /// Calculate IsOptedIn status based on OptedIn status from all installed versions of VS. /// If all found OptedIn statuses are true we return true, otherwise we return false. /// </summary> /// <param name="session">Host telemetry session</param> /// <returns>OptedIn status</returns> public bool ReadIsOptedInStatus(TelemetrySession session) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(session, "session"); bool flag = false; OptinStatus optinStatus = OptinStatus.Undefined; if (TryGlobalPolicyOptedInStatus(out bool optedIn)) { flag = optedIn; optinStatus = OptinStatus.ReadFromGlobalPolicy; } else { bool flag2 = false; bool flag3 = false; string[] registrySubKeyNamesFromLocalMachineRoot = registryTools.GetRegistrySubKeyNamesFromLocalMachineRoot("Software\\Microsoft\\VSCommon", false); if (registrySubKeyNamesFromLocalMachineRoot != null && registrySubKeyNamesFromLocalMachineRoot.Length != 0) { string[] array = registrySubKeyNamesFromLocalMachineRoot; foreach (string text in array) { if (!KeyMatchesSqmFormat(text)) { continue; } int?registryIntValueFromLocalMachineRoot = ((IRegistryTools)registryTools).GetRegistryIntValueFromLocalMachineRoot(string.Format(CultureInfo.InvariantCulture, "Software\\Microsoft\\VSCommon\\{0}\\SQM", new object[1] { text }), "OptIn", (int?)null); if (registryIntValueFromLocalMachineRoot.HasValue) { if (registryIntValueFromLocalMachineRoot.Value == 1) { flag2 = true; } else { flag3 = true; } } } } flag = (flag2 && !flag3); if (flag2 && !flag3) { optinStatus = OptinStatus.OptedInForAll; } else if (flag2 && flag3) { optinStatus = OptinStatus.OptedInForSomeOptedOutForSome; } else if (!flag2 && flag3) { optinStatus = OptinStatus.OptedOutForAll; } } session.PostProperty("vs.core.usevsisoptedinstatus", optinStatus.ToString()); return(flag); }
/// <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); }
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> /// Build EventProcessorChannel and all its dependencies /// </summary> /// <param name="hostSession"></param> public void Build(TelemetrySession hostSession) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(hostSession, "hostSession"); EventProcessorRouter = BuildRouter(); EventProcessorContext = BuildContext(hostSession, EventProcessorRouter); EventProcessor = BuildProcessor(hostSession, EventProcessorContext); EventProcessorChannel = BuildChannel(EventProcessor, hostSession); }
/// <summary> /// Build WatsonChannelBuilder and all its dependencies /// </summary> /// <param name="hostSession"></param> public void Build(TelemetrySession hostSession) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(hostSession, "hostSession"); WatsonSessionChannel = new WatsonSessionChannel(hostSession, faultEventSamplePercent, faultEventMaximumWatsonReportsPerSession, faultEventMinimumSecondsBetweenWatsonReports) { Properties = properties }; }
/// <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); }
/// <summary> /// Start tracking operation by posting a <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> with specified properties at the begining of operation work, /// and return a <see cref="T:Coding4Fun.VisualStudio.Telemetry.TelemetryScope`1" /> object. /// When the user task finishes, call method <see cref="M:Coding4Fun.VisualStudio.Telemetry.TelemetryScope`1.End(Coding4Fun.VisualStudio.Telemetry.TelemetryResult,System.String)" /> to post another <see cref="T:Coding4Fun.VisualStudio.Telemetry.OperationEvent" /> for end point. /// Because the same event name is used by both start and end events, please don't use Start or End in event name. /// </summary> /// <param name="session">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="severity"> /// A severity level of the event. /// The level is used for event consumer (e.g., ETW provider, backend reporting) to organize data easier. /// </param> /// <param name="startEventProperties"> /// Event properties for the start event of this scope. They are also copied to end event. /// </param> /// <param name="correlations">Events with which this scope can correlate.</param> /// <returns><see cref="T:Coding4Fun.VisualStudio.Telemetry.TelemetryScope`1" /> instance.</returns> public static TelemetryScope <OperationEvent> StartOperation(this TelemetrySession session, string eventName, TelemetrySeverity severity, IDictionary <string, object> startEventProperties, TelemetryEventCorrelation[] correlations) { TelemetryScopeSettings settings = new TelemetryScopeSettings { Severity = severity, StartEventProperties = startEventProperties, Correlations = correlations }; return(session.StartOperation(eventName, settings)); }
/// <summary> /// Post Identity telemetry. Generates an event with properties and sends it. /// </summary> /// <param name="telemetrySession"></param> public void PostIdentityTelemetryWhenSessionInitialized(TelemetrySession telemetrySession) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(telemetrySession, "telemetrySession"); if (!telemetrySession.IsSessionCloned) { Scheduler.Schedule(delegate { CollectAndSendIdentityEvaluationValuesEvent(telemetrySession, telemetrySession.CancellationToken); }, telemetrySession.CancellationToken); } }
/// <summary> /// Initializes all TelemetryManifestMatchSample.IsSampleActive. /// The initialization is based on information from the given session, /// such as machine id, session id etc. /// </summary> /// <param name="session"></param> /// <returns></returns> internal string CalculateAllSamplings(TelemetrySession session) { StringBuilder stringBuilder = new StringBuilder("["); foreach (TelemetryManifestRule item in ObjectExtensions.EmptyIfNull <TelemetryManifestRule>(Rules)) { stringBuilder.AppendFormat("{0}, ", item.CalculateAllSamplings(session)); } stringBuilder.Append("]"); return(stringBuilder.ToString()); }
private void PostAnyFaultsGettingHardwareId(TelemetrySession telemetrySession, CancellationToken cancellationToken) { foreach (Exception item in ExceptionsEncounteredObtainingHardwareId) { if (cancellationToken.IsCancellationRequested) { break; } telemetrySession.PostFault(HardwareIdEventFaultName, "ExceptionObtainingHardwareId", item); } }
private void PostPersistedSharedProperties(TelemetrySession telemetrySession, CancellationToken cancellationToken) { if (!ExceptionsEncounteredObtainingHardwareId.Any()) { string b = telemetrySession.GetPersistedSharedProperty(IdentityPropertyProvider.HardwareIdPropertyName) as string; string hardwareId = HardwareId; if (HardwareId != HardwareIdNotObtained && !string.Equals(hardwareId, b, StringComparison.Ordinal)) { telemetrySession.SetPersistedSharedProperty(IdentityPropertyProvider.HardwareIdPropertyName, hardwareId); } } }
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(); }
public TelemetryEventDataVerbose(TelemetrySession session, TelemetryEvent telemetryEvent) { SessionId = ((session != null) ? session.SessionId : string.Empty); HostName = ((session != null) ? session.HostName : string.Empty); if (telemetryEvent.HasProperties) { Properties = telemetryEvent.Properties.Select((KeyValuePair <string, object> kvp) => new KeyValuePair <string, string>(kvp.Key, Convert.ToString(kvp.Value, CultureInfo.InvariantCulture))); } else { Properties = null; } }
public string CalculateAllSamplings(TelemetrySession session) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendFormat("{0}{{", Name); foreach (TelemetryManifestMatchSampling allSampling in GetAllSamplings()) { allSampling.CalculateIsSampleActive(this, session); stringBuilder.AppendFormat("{0}, ", allSampling.GetFullName(this)); } stringBuilder.Append("}"); return(stringBuilder.ToString()); }
/// <summary> /// Writes an event for a TelemetryActivity when it is posted to a session. /// </summary> /// <param name="activity">Telemetry activity instance</param> /// <param name="session"></param> public void WriteActivityPostEvent(TelemetryActivity activity, TelemetrySession session) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) EventSourceOptions val = default(EventSourceOptions); val.Keywords = ((EventKeywords)8); val.Level = ((EventLevel)5); EventSourceOptions options = val; WriteEventWithActivityId <TelemetryEventData>(userData: new TelemetryEventData(session), telemetryEvent: activity, eventName: activity.Name + "/Posted", options: options); }
public void SchedulePostPersistedSharedPropertyAndSendAnyFaults(TelemetrySession telemetrySession, ITelemetryScheduler scheduler) { CodeContract.RequiresArgumentNotNull <TelemetrySession>(telemetrySession, "telemetrySession"); if (IsMachineStoreAccessible) { scheduler.Schedule(delegate { PostAnyFaultsGettingHardwareId(telemetrySession, telemetrySession.CancellationToken); }, telemetrySession.CancellationToken); scheduler.Schedule(delegate { PostPersistedSharedProperties(telemetrySession, telemetrySession.CancellationToken); }, telemetrySession.CancellationToken); } }
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); } }
/// <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); }
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> /// Allow user to change the Default Session, especially for a cloned session /// e.g. TelemetryService.SetDefaultSession(new TelemetrySession(clonedSettingsString) /// </summary> /// <param name="telemetrySession"></param> public static void SetDefaultSession(TelemetrySession telemetrySession) { bool flag = true; if (InternalDefaultSession == null) { lock (lockDefaultSessionCreation) { if (InternalDefaultSession == null) { InternalDefaultSession = telemetrySession; flag = false; } } } if (flag) { throw new InvalidOperationException("Cannot change default session when already set"); } }
/// <summary> /// Writes an event to indicate a telemetry event being posted to a session /// </summary> /// <param name="telemetryEvent">Telemetry event instance</param> /// <param name="session"></param> public void WriteTelemetryPostEvent(TelemetryEvent telemetryEvent, TelemetrySession session) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (telemetryEvent is TelemetryActivity) { throw new ArgumentException("Telemetry Activity instances should call WriteActivityPostEvent", "telemetryEvent"); } EventSourceOptions val = default(EventSourceOptions); val.Opcode = ((EventOpcode)0); val.Keywords = ((EventKeywords)4); val.Level = ((EventLevel)4); EventSourceOptions options = val; WriteTelemetryEventSimple(telemetryEvent, options, session); WriteTelemetryEventExtended(telemetryEvent, session); }
/// <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 default session channels and return IEnumerable list of them. /// In the case when checkPendingAsimovEvents == true call method on Vortex channel /// to check whether pending telemetry is exists and in case existing Start this channel /// immediately. /// </summary> /// <param name="telemetrySession"></param> /// <param name="checkPendingAsimovEvents"></param> /// <returns></returns> public IEnumerable <ISessionChannel> CreateSessionChannels(TelemetrySession telemetrySession, bool checkPendingAsimovEvents) { IStorageBuilder storageBuilder = GetStorageBuilder(); IProcessLockFactory processLockFactory = GetProcessLock(); if (AppInsightsInstrumentationKey != null) { yield return(new DefaultAppInsightsSessionChannel(AppInsightsInstrumentationKey, telemetrySession.UserId.ToString(), storageBuilder, processLockFactory)); } if (AsimovInstrumentationKey != null) { AsimovAppInsightsSessionChannel asimovAppInsightsSessionChannel = new AsimovAppInsightsSessionChannel("aivortex", false, AsimovInstrumentationKey, telemetrySession.UserId.ToString(), ChannelProperties.Default | ChannelProperties.NotForUnitTest, telemetrySession, storageBuilder, processLockFactory); if (checkPendingAsimovEvents) { asimovAppInsightsSessionChannel.CheckPendingEventsAndStartChannel(telemetrySession.SessionId); } yield return(asimovAppInsightsSessionChannel); yield return(new AsimovAppInsightsSessionChannel("aiasimov", Platform.IsWindows, AsimovInstrumentationKey, telemetrySession.UserId.ToString(), ChannelProperties.NotForUnitTest, telemetrySession, storageBuilder, processLockFactory)); } yield return(new TelemetryLogToFileChannel()); }