private void SetPersistedSharedProperty(string propertyName, object propertyValue, Action addToBagAction) { if (!base.IsDisposed) { CodeContract.RequiresArgumentNotNullAndNotWhiteSpace(propertyName, "propertyName"); dynamic persistedSharedProperty = GetPersistedSharedProperty(propertyName); addToBagAction(); defaultContext.SharedProperties[propertyName] = propertyValue; if (persistedSharedProperty == null || !persistedSharedProperty.Equals(propertyValue)) { TelemetryEvent telemetryEvent = new TelemetryEvent("VS/TelemetryApi/PersistedSharedProperty/Set"); telemetryEvent.Properties["VS.TelemetryApi.PersistedSharedProperty.Name"] = propertyName; telemetryEvent.Properties["VS.TelemetryApi.PersistedSharedProperty.IsChangedValue"] = (object)(persistedSharedProperty != null); PostEvent(telemetryEvent); } } }
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> /// Execute action on event, using telemetryManifestContext as a provider of the necessary information. /// Return true if it is allowed to execute next actions. /// Return false action forbids the event. /// By default OptOut set IsEventDropped to the true, and exclude all properties. /// </summary> /// <param name="eventProcessorContext"></param> /// <returns>Indicator, whether current action is not explicitely forbid current event</returns> public bool Execute(IEventProcessorContext eventProcessorContext) { if (!eventProcessorContext.HostTelemetrySession.IsOptedIn) { TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; if (!telemetryEvent.IsOptOutFriendly && !optoutFriendlyEvents.Contains(telemetryEvent.Name)) { eventProcessorContext.IsEventDropped = true; } foreach (string item in new List <string>(telemetryEvent.Properties.Keys)) { if ((!telemetryEvent.IsOptOutFriendly || TelemetryEvent.IsPropertyNameReserved(item) || TelemetryContext.IsPropertyNameReserved(item)) && !optoutFriendlyProperties.Contains(item)) { eventProcessorContext.ExcludePropertyFromEvent(item); } } } return(true); }
/// <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> /// 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); } }
internal void PostValidatedEvent(TelemetryEvent telemetryEvent) { if (!base.IsDisposed) { TelemetryEvent telemetryEvent2 = telemetryEvent.BuildChannelEvent(ProcessStartTime, SessionId); AddContextProperties(telemetryEvent2); telemetryEvent2.PostTimestamp = DateTimeOffset.Now; RawTelemetryEventReceived?.Invoke(this, new TelemetryTestChannelEventArgs { Event = telemetryEvent2 }); if (!isInitialized) { telemetryBufferChannel.PostEvent(telemetryEvent2); } else { PostProcessedEvent(telemetryEvent2); } } }
/// <summary> /// Process event, using dynamic telemetry settings. /// Called from the background thread. /// </summary> /// <param name="telemetryEvent"></param> public void ProcessEvent(TelemetryEvent telemetryEvent) { RequiresNotDisposed(); CodeContract.RequiresArgumentNotNull <TelemetryEvent>(telemetryEvent, "telemetryEvent"); if (CurrentManifest == null) { throw new NullReferenceException("CurrentManifest"); } IEnumerable <IEventProcessorAction> mergedCustomAndManifestActionsInOrder = GetMergedCustomAndManifestActionsInOrder(CurrentManifest.GetActionsForEvent(telemetryEvent)); bool flag = true; eventProcessorContext.InitForNewEvent(telemetryEvent); foreach (IEventProcessorAction item in mergedCustomAndManifestActionsInOrder) { flag = !item.Execute(eventProcessorContext); if (flag) { break; } } eventProcessorContext.Router.RouteEvent(telemetryEvent, mainSession.SessionId, flag || eventProcessorContext.IsEventDropped); }
/// <summary> /// Post cooked event to the available channels. In case if event is dropped (isDropped == true) /// we still want to post this event to the DevChannel if any. Dev channel is used for the testing /// purposes. /// </summary> /// <param name="telemetryEvent"></param> /// <param name="sessionId"></param> /// <param name="isDropped"></param> public void RouteEvent(TelemetryEvent telemetryEvent, string sessionId, bool isDropped) { List <Tuple <ISessionChannel, IEnumerable <ITelemetryManifestRouteArgs> > > list = new List <Tuple <ISessionChannel, IEnumerable <ITelemetryManifestRouteArgs> > >(); foreach (ISessionChannel channel in channelList) { bool flag = (channel.Properties & ChannelProperties.DevChannel) != 0; if (flag || (!isDropped && !IsChannelDisabled(channel.ChannelId))) { IEnumerable <ITelemetryManifestRouteArgs> routeArguments = null; bool flag2 = TryGetRouteArgument(channel.ChannelId, out routeArguments); if ((flag | flag2) || (channel.Properties & (ChannelProperties.Default | ChannelProperties.Test | ChannelProperties.DevChannel)) != 0) { if (!channel.IsStarted) { channel.Start(sessionId); } list.Add(Tuple.Create(channel, routeArguments)); } } } if (list.Count > 0) { telemetryEvent.Properties["Reserved.ChannelUsed"] = StringExtensions.Join(from item in list where (item.Item1.Properties & ChannelProperties.DevChannel) == 0 select item.Item1.TransportUsed, ","); foreach (Tuple <ISessionChannel, IEnumerable <ITelemetryManifestRouteArgs> > item in list) { if (item.Item2 == null) { item.Item1.PostEvent(telemetryEvent); } else { item.Item1.PostEvent(telemetryEvent, item.Item2); } } } }
private void WriteTelemetryEventExtended(TelemetryEvent telemetryEvent, TelemetrySession session = null) { //IL_000e: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) EventKeywords val = (EventKeywords)((telemetryEvent is TelemetryActivity) ? 8 : 4); if (telemetryEventSource.IsEnabled((EventLevel)5, val)) { EventSourceOptions val2 = default(EventSourceOptions); val2.Opcode = ((EventOpcode)0); val2.Keywords = (val); val2.Level = ((EventLevel)5); EventSourceOptions options = val2; TelemetryEventDataVerbose userData = new TelemetryEventDataVerbose(session, telemetryEvent); string eventName = telemetryEvent.Name + "/Verbose"; WriteEventWithActivityId(telemetryEvent, eventName, options, userData); } }
/// <summary> /// Execute action on event, using eventProcessorContext as a provider of the necessary information. /// This action add a suffix DataModelSetting to all Setting property names in the event. /// </summary> /// <param name="eventProcessorContext"></param> /// <returns> /// Indicator, whether current action is not explicitely forbid current event. /// Return true if it is allowed to execute next actions. /// Return false action forbids the event. /// </returns> public bool Execute(IEventProcessorContext eventProcessorContext) { CodeContract.RequiresArgumentNotNull <IEventProcessorContext>(eventProcessorContext, "eventProcessorContext"); TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; KeyValuePair <string, T>[] array = (from prop in telemetryEvent.Properties where prop.Value is T select new KeyValuePair <string, T>(prop.Key, prop.Value as T)).ToArray(); totalPropertyCount += array.Length; if (array.Any()) { telemetryEvent.Properties[flagPropertyName] = true; } KeyValuePair <string, T>[] array2 = array; for (int i = 0; i < array2.Length; i++) { KeyValuePair <string, T> keyValuePair = array2[i]; telemetryEvent.Properties[keyValuePair.Key + SuffixName] = keyValuePair.Value.Value; telemetryEvent.Properties.Remove(keyValuePair.Key); properties.Add(keyValuePair.Key); } return(true); }
/// <summary> /// Queues a telemetry event to be posted to a server. /// Choose this method for flexibility. /// You should consider choosing PostUserTask, PostOperation, PostFault or PostAsset. /// These will enable a richer telemetry experience with additional insights provided by Visual Studio Data Model. /// If your data point doesn't align with any VS Data Model entity, please don't force any association and continue to use this method. /// If you have any questions regarding VS Data Model, please email VS Data Model Crew ([email protected]). /// </summary> /// <param name="telemetryEvent">A telemetry event that is ready to be posted.</param> public void PostEvent(TelemetryEvent telemetryEvent) { if (base.IsDisposed) { return; } bool flag = true; FaultEvent faultEvent = telemetryEvent as FaultEvent; if (faultEvent != null && watsonSessionChannel != null) { watsonSessionChannel.PostEvent(faultEvent); flag = faultEvent.PostThisEventToTelemetry; } if (flag) { if (!customEventPostProtection.TryEnterReadLock(0)) { numberOfDroppedEventsInDisposing++; return; } ValidateEvent(telemetryEvent); TelemetryContext.ValidateEvent(telemetryEvent); PostValidatedEvent(telemetryEvent); customEventPostProtection.ExitReadLock(); } TelemetryActivity telemetryActivity = telemetryEvent as TelemetryActivity; if (telemetryActivity != null) { TelemetryService.TelemetryEventSource.WriteActivityPostEvent(telemetryActivity, this); } else { TelemetryService.TelemetryEventSource.WriteTelemetryPostEvent(telemetryEvent, this); } }
/// <summary> /// Context event validator. We have to check that properties doesn't contain reserved prefixes /// </summary> /// <param name="telemetryEvent"></param> internal static void ValidateEvent(TelemetryEvent telemetryEvent) { CodeContract.RequiresArgumentNotNull <TelemetryEvent>(telemetryEvent, "telemetryEvent"); ValidateEventName(telemetryEvent); ValidateEventProperties(telemetryEvent); }
public bool IsEventMatch(TelemetryEvent telemetryEvent) { return(IsSampleActive); }
/// <summary> /// Validate event. Ensure that event regular properties doesn't contain Reserved. prefix /// </summary> /// <param name="telemetryEvent"></param> internal static void ValidateEvent(TelemetryEvent telemetryEvent) { CodeContract.RequiresArgumentNotNull <TelemetryEvent>(telemetryEvent, "telemetryEvent"); foreach (KeyValuePair <string, object> property in telemetryEvent.Properties) { if (property.Key.StartsWith("Reserved.", StringComparison.Ordinal) && TelemetryEvent.IsPropertyNameReserved(property.Key)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "property '{0}' has reserved prefix 'Reserved'", new object[1] { property.Key })); } } }
/// <summary> /// Check, whether does event match conditions /// </summary> /// <param name="telemetryEvent"></param> /// <returns></returns> public bool IsEventMatch(TelemetryEvent telemetryEvent) { throw new NotImplementedException(); }
/// <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. /// </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"); EnsureSerializerIsInitialized(); TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; List <KeyValuePair <string, string> > list = new List <KeyValuePair <string, string> >(); Dictionary <string, string> dictionary = new Dictionary <string, string>(); foreach (KeyValuePair <string, object> property in telemetryEvent.Properties) { if (property.Value is TelemetryComplexProperty) { try { SerializeProperty(property.Key, property.Value as TelemetryComplexProperty, eventProcessorContext, list); } catch (ComplexObjectSerializerException ex) { dictionary.Add(property.Key, ex.Message); } } } if (dictionary.Count > 0) { try { SerializeProperty("Reserved.ComplexProperty.FailedToSerialize", new TelemetryComplexProperty(dictionary), eventProcessorContext, list); } catch { } } foreach (KeyValuePair <string, string> item in dictionary) { telemetryEvent.Properties.Remove(item.Key); } HashSet <string> hashSet = new HashSet <string>(); foreach (KeyValuePair <string, string> item2 in list) { if (item2.Value.Length <= 61440) { telemetryEvent.Properties[item2.Key] = item2.Value; } else { telemetryEvent.Properties[item2.Key] = item2.Value.Substring(0, 61437) + "..."; hashSet.Add(item2.Key); } } if (hashSet.Count > 0) { list.Clear(); try { SerializeProperty("Reserved.ComplexProperty.Truncated", new TelemetryComplexProperty(hashSet), eventProcessorContext, list); } catch { } foreach (KeyValuePair <string, string> item3 in list) { telemetryEvent.Properties[item3.Key] = item3.Value; } } return(true); }
/// <summary> /// Validate coming event /// </summary> /// <param name="eventProcessorContext"></param> /// <returns></returns> public bool Execute(IEventProcessorContext eventProcessorContext) { TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; if (TelemetryContext.IsEventNameContextPostProperty(telemetryEvent.Name)) { return(telemetryEvent.Properties.Any((KeyValuePair <string, object> p) => !TelemetryEvent.IsPropertyNameReserved(p.Key) && !TelemetryContext.IsPropertyNameReserved(p.Key))); } return(true); }
/// <summary> /// Execute action on event, using telemetryManifestContext as a provider of the necessary information. /// Return true if it is allowed to execute next actions. /// Return false action forbids the event. /// </summary> /// <param name="eventProcessorContext"></param> /// <returns>Indicator, whether current action is not explicitely forbid current event</returns> public bool Execute(IEventProcessorContext eventProcessorContext) { List <string> list = null; List <Tuple <string, string> > list2 = null; TelemetryEvent telemetryEvent = eventProcessorContext.TelemetryEvent; foreach (KeyValuePair <string, object> property in telemetryEvent.Properties) { if (!IsPropertyNameValid(property.Key)) { if (list == null) { list = new List <string>(); } list.Add(property.Key); } else if (property.Value != null && !(property.Value is TelemetryComplexProperty)) { string text = property.Value.ToString(); if (!IsPropertyValueValid(text)) { if (list2 == null) { list2 = new List <Tuple <string, string> >(); } list2.Add(Tuple.Create(property.Key, text)); } } } if (list != null) { StringBuilder stringBuilder = new StringBuilder(); foreach (string item in list) { telemetryEvent.Properties.Remove(item); if (stringBuilder.Length + 1 + item.Length <= 1024) { if (stringBuilder.Length > 0) { stringBuilder.AppendFormat(CultureInfo.InvariantCulture, ",{0}", new object[1] { item }); } else { stringBuilder.Append(item); } } else if (stringBuilder.Length == 0) { stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}...", new object[1] { item.Substring(0, 147) }); } } telemetryEvent.Properties["Reserved.InvalidEvent.InvalidPropertyNames"] = stringBuilder.ToString(); } if (list2 != null) { StringBuilder stringBuilder2 = new StringBuilder(); foreach (Tuple <string, string> item2 in list2) { telemetryEvent.Properties[item2.Item1] = string.Format(CultureInfo.InvariantCulture, "{0}...", new object[1] { item2.Item2.Substring(0, 1021) }); if (stringBuilder2.Length + 1 + item2.Item1.Length <= 150) { if (stringBuilder2.Length > 0) { stringBuilder2.AppendFormat(CultureInfo.InvariantCulture, ",{0}", new object[1] { item2.Item1 }); } else { stringBuilder2.Append(item2.Item1); } } } telemetryEvent.Properties["Reserved.InvalidEvent.TruncatedProperties"] = stringBuilder2.ToString(); } return(true); }
/// <summary> /// Check, whether does event match conditions /// </summary> /// <param name="telemetryEvent"></param> /// <returns></returns> public bool IsEventMatch(TelemetryEvent telemetryEvent) { CodeContract.RequiresArgumentNotNull <TelemetryEvent>(telemetryEvent, "telemetryEvent"); return(eventMatchFilter.IsEventMatch(telemetryEvent)); }
/// <summary> /// Add reserved properties (Id and Name) to the event /// <a href="http://devdiv/sites/vsplat/Fundamentals/Shared Documents/Telemetry/Projects/Telemetry API/TelemetrySession Speclet.docx?Web=1" /> /// </summary> /// <param name="telemetryEvent"></param> private void AddReservedPropertiesToTheEvent(TelemetryEvent telemetryEvent) { telemetryEvent.ReservedProperties["ContextName"] = ContextName; }