public void AddRange_OtherIsNotEmpty_ShouldAggregate()
        {
            // Arrange
            var target = new Dictionary <string, int>
            {
                { "one", 5 },
                { "two", 34 }
            };

            var other = new Dictionary <string, int>
            {
                { "two", 67 },
                { "three", 2 }
            };

            // Act
            DictionaryExtensions.AddRange(target, other, (lhs, rhs) => lhs + rhs);

            // Assert
            target.ShouldBeEquivalentTo(new Dictionary <string, int>
            {
                { "one", 5 },
                { "two", 34 + 67 },
                { "three", 2 }
            });
        }
Example #2
0
        /// <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);
        }
 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();
 }
Example #4
0
        /// <summary>
        /// Don't want to expose an interface, like IClonable publicly, so we use an internal method that clones from a ChannelEvent
        /// </summary>
        /// <returns></returns>
        internal TelemetryEvent CloneTelemetryEvent()
        {
            TelemetryEvent obj = new TelemetryEvent(eventName, Severity, EventType)
            {
                eventId          = eventId,
                IsOptOutFriendly = IsOptOutFriendly,
                Correlation      = Correlation,
                PostTimestamp    = PostTimestamp
            };

            DictionaryExtensions.AddRange <string, object>((IDictionary <string, object>)obj.eventProperties, (IDictionary <string, object>)eventProperties, true);
            obj.ReservedProperties.Clear();
            DictionaryExtensions.AddRange <string, object>(obj.ReservedProperties, ReservedProperties, true);
            return(obj);
        }
Example #5
0
        /// <summary>
        /// Creates an event for a channel from this event and session start time.
        /// Note: a returned event is not a pure copy of this event.
        /// </summary>
        /// <param name="processStartTime"></param>
        /// <param name="sessionId"></param>
        /// <returns></returns>
        internal TelemetryEvent BuildChannelEvent(long processStartTime, string sessionId)
        {
            eventId = Guid.NewGuid();
            TelemetryEvent telemetryEvent = new TelemetryEvent(eventName, Severity, EventType);

            telemetryEvent.IsOptOutFriendly = IsOptOutFriendly;
            telemetryEvent.Correlation      = Correlation;
            foreach (KeyValuePair <string, object> allProperty in GetAllProperties(DateTime.UtcNow.Ticks, processStartTime, sessionId))
            {
                telemetryEvent.eventProperties[allProperty.Key] = allProperty.Value;
            }
            telemetryEvent.ReservedProperties.Clear();
            DictionaryExtensions.AddRange <string, object>(telemetryEvent.ReservedProperties, ReservedProperties, true);
            return(telemetryEvent);
        }
        public void AddRange_ThisIsEmpty_ShiuldMerge()
        {
            // Arrange
            var other = new Dictionary <string, int>
            {
                { "one", 5 },
                { "two", 34 }
            };

            var target = new Dictionary <string, int>();

            // Act
            DictionaryExtensions.AddRange(target, other, (lhs, rhs) => lhs + rhs);

            // Assert
            target.ShouldBeEquivalentTo(other);
        }
        public void AddRange_OtherIsEmpty_DoNothing()
        {
            // Arrange
            var expected = new Dictionary <string, int>
            {
                { "one", 5 },
                { "two", 34 }
            };

            var target = new Dictionary <string, int>(expected);

            // Act
            DictionaryExtensions.AddRange(target, null, (lhs, rhs) => lhs + rhs);

            // Assert
            target.ShouldBeEquivalentTo(expected);
        }
 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);
     });
 }
Example #9
0
        /// <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;
        }
 public void WhenSourceIsNull_ThenThrowException()
 {
     Assert.Throws <ArgumentNullException>(() => DictionaryExtensions.AddRange(null, new KeyValuePair <string, string> [0]));
 }