Beispiel #1
0
        public void QuickPulseServiceClientFillsInSampleWeightWhenSubmittingToService()
        {
            // ARRANGE
            var now           = DateTimeOffset.UtcNow;
            var serviceClient = new QuickPulseServiceClient(this.serviceEndpoint, string.Empty, string.Empty, string.Empty, string.Empty, new Clock());
            var sample1       =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator
            {
                AIRequestCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(3, 10000),
                StartTimestamp = now,
                EndTimestamp   = now.AddSeconds(1)
            },
                    new Dictionary <string, Tuple <PerformanceCounterData, float> >());

            var sample2 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator
            {
                AIDependencyCallCountAndDurationInTicks =
                    QuickPulseDataAccumulator.EncodeCountAndDuration(4, 10000),
                StartTimestamp = now,
                EndTimestamp   = now.AddSeconds(1)
            },
                    new Dictionary <string, Tuple <PerformanceCounterData, float> >());

            // ACT
            serviceClient.SubmitSamples(new[] { sample1, sample2 }, string.Empty);

            // ASSERT
            this.listener.Stop();

            Assert.AreEqual(3, this.samples[0].Item2.Metrics.Single(m => m.Name == @"\ApplicationInsights\Request Duration").Weight);
            Assert.AreEqual(4, this.samples[1].Item2.Metrics.Single(m => m.Name == @"\ApplicationInsights\Dependency Call Duration").Weight);
        }
Beispiel #2
0
        public void QuickPulseDataAccumulatorCollectsTelemetryItemsInThreadSafeManner()
        {
            // ARRANGE
            CollectionConfigurationError[] errors;
            var accumulator =
                new QuickPulseDataAccumulator(
                    new CollectionConfiguration(
                        new CollectionConfigurationInfo()
            {
                ETag = string.Empty, Metrics = new CalculatedMetricInfo[0]
            },
                        out errors,
                        new ClockMock()));

            // ACT
            var iterationCount = 1000;
            var concurrency    = 12;

            Action addItemTask =
                () =>
                Enumerable.Range(0, iterationCount)
                .ToList()
                .ForEach(
                    i => accumulator.TelemetryDocuments.Push(new RequestTelemetryDocument()
            {
                Name = i.ToString(CultureInfo.InvariantCulture)
            }));

            var tasks = new List <Action>();

            for (int i = 0; i < concurrency; i++)
            {
                tasks.Add(addItemTask);
            }

            Parallel.Invoke(new ParallelOptions()
            {
                MaxDegreeOfParallelism = concurrency
            }, tasks.ToArray());

            // ASSERT
            var dict = new Dictionary <int, int>();

            foreach (var item in accumulator.TelemetryDocuments)
            {
                int requestNumber = int.Parse(((RequestTelemetryDocument)item).Name, CultureInfo.InvariantCulture);
                if (dict.ContainsKey(requestNumber))
                {
                    dict[requestNumber]++;
                }
                else
                {
                    dict[requestNumber] = 1;
                }
            }

            Assert.AreEqual(iterationCount, dict.Count);
            Assert.IsTrue(dict.All(pair => pair.Value == concurrency));
        }
 private static QuickPulseDataSample CreateDataSample(
     QuickPulseDataAccumulator accumulator,
     IEnumerable <Tuple <PerformanceCounterData, double> > perfData,
     IEnumerable <Tuple <string, int> > topCpuData,
     bool topCpuDataAccessDenied)
 {
     return(new QuickPulseDataSample(
                accumulator,
                perfData.ToDictionary(tuple => tuple.Item1.ReportAs, tuple => tuple),
                topCpuData,
                topCpuDataAccessDenied));
 }
        private QuickPulseDataSample CollectSample()
        {
            // For AI data, all we have to do is lock the current accumulator in
            QuickPulseDataAccumulator completeAccumulator = this.dataAccumulatorManager.CompleteCurrentDataAccumulator();

            // For performance collection, we have to read perf samples from Windows
            List <Tuple <PerformanceCounterData, float> > perfData =
                this.performanceCollector.Collect((counterName, e) => QuickPulseEventSource.Log.CounterReadingFailedEvent(e.ToString(), counterName))
                .ToList();

            return(this.CreateDataSample(completeAccumulator, perfData));
        }
        public void QuickPulseDataAccumulatorEncodesCountAndDurationOverflowDuration()
        {
            // ARRANGE

            // ACTt
            long encodedValue = QuickPulseDataAccumulator.EncodeCountAndDuration(MaxCount, MaxDuration + 1);
            Tuple <long, long> decodedValues = QuickPulseDataAccumulator.DecodeCountAndDuration(encodedValue);

            // ASSERT
            Assert.AreEqual(0, decodedValues.Item1);
            Assert.AreEqual(0, decodedValues.Item2);
        }
        public void QuickPulseDataAccumulatorEncodesCountAndDuration()
        {
            // ARRANGE
            long count    = 42;
            long duration = 102;

            // ACT
            long encodedValue = QuickPulseDataAccumulator.EncodeCountAndDuration(count, duration);
            Tuple <long, long> decodedValues = QuickPulseDataAccumulator.DecodeCountAndDuration(encodedValue);

            // ASSERT
            Assert.AreEqual(count, decodedValues.Item1);
            Assert.AreEqual(duration, decodedValues.Item2);
        }
        public void QuickPulseDataSampleHandlesAbsentCounterInPerfData()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.IsFalse(dataSample.PerfCountersLookup.Any());
        }
        private void UpdateRequestAggregates(RequestTelemetry requestTelemetry)
        {
            long requestCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(1, requestTelemetry.Duration.Ticks);

            Interlocked.Add(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestCountAndDurationInTicks, requestCountAndDurationInTicks);

            if (requestTelemetry.Success == true)
            {
                Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestSuccessCount);
            }
            else
            {
                Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestFailureCount);
            }
        }
Beispiel #9
0
        public void QuickPulseDataSampleHandlesAbsentCounterInPerfData()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(0.0, dataSample.PerfIisQueueSize);
        }
        public void QuickPulseDataSampleHandlesAbsentTopCpuData()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.IsFalse(dataSample.TopCpuData.Any());
        }
        public void QuickPulseDataSampleHandlesAbsentTopCpuData()
        {
            // ARRANGE
            var accumulator =
                new QuickPulseDataAccumulator(new CollectionConfiguration(EmptyCollectionConfigurationInfo, out this.errors, new ClockMock()))
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.IsFalse(dataSample.TopCpuData.Any());
        }
        public void QuickPulseDataSampleCalculatesAIDependencyCallsFailedPerSecondCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = this.now,
                EndTimestamp   = this.now.AddSeconds(2),
                AIDependencyCallFailureCount = 10
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.AreEqual(10.0 / 2, dataSample.AIDependencyCallsFailedPerSecond);
        }
        public void QuickPulseDataSampleCalculatesAIRpsCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2),
                AIRequestCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(10, 0)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(10.0 / 2, dataSample.AIRequestsPerSecond);
        }
        public void QuickPulseDataSampleCalculatesAIExceptionsPerSecondCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp   = DateTimeOffset.UtcNow,
                EndTimestamp     = DateTimeOffset.UtcNow.AddSeconds(2),
                AIExceptionCount = 3
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(3.0 / 2, dataSample.AIExceptionsPerSecond);
        }
        public void QuickPulseDataSampleTimestampsItselfCorrectly()
        {
            // ARRANGE
            var timestampStart = DateTimeOffset.UtcNow;
            var timestampEnd   = DateTimeOffset.UtcNow.AddSeconds(3);
            var accumulator    = new QuickPulseDataAccumulator {
                StartTimestamp = timestampStart, EndTimestamp = timestampEnd
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(timestampStart, dataSample.StartTimestamp);
            Assert.AreEqual(timestampEnd, dataSample.EndTimestamp);
        }
        public void QuickPulseDataSampleCalculatesAIDependencyCallsSucceededPerSecondCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2),
                AIDependencyCallSuccessCount = 10
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(10.0 / 2, dataSample.AIDependencyCallsSucceededPerSecond);
        }
        public void QuickPulseDataSampleCalculatesAIRequestDurationAveCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2),
                AIRequestCountAndDurationInTicks =
                    QuickPulseDataAccumulator.EncodeCountAndDuration(10, TimeSpan.FromSeconds(5).Ticks)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(TimeSpan.FromSeconds(5).TotalMilliseconds / 10.0, dataSample.AIRequestDurationAveInMs);
        }
        public void QuickPulseDataSampleCalculatesAIDependencyCallDurationAveWhenDependencyCallCountIsZeroCorrectly()
        {
            // ARRANGE
            var accumulator =
                new QuickPulseDataAccumulator(new CollectionConfiguration(EmptyCollectionConfigurationInfo, out this.errors, new ClockMock()))
            {
                StartTimestamp = this.now,
                EndTimestamp   = this.now.AddSeconds(2),
                AIDependencyCallCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(0, TimeSpan.FromSeconds(5).Ticks)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.AreEqual(0.0, dataSample.AIDependencyCallDurationAveInMs);
        }
        private void UpdateDependencyAggregates(DependencyTelemetry dependencyTelemetry)
        {
            long dependencyCallCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(1, dependencyTelemetry.Duration.Ticks);

            Interlocked.Add(
                ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallCountAndDurationInTicks,
                dependencyCallCountAndDurationInTicks);

            if (dependencyTelemetry.Success == true)
            {
                Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallSuccessCount);
            }
            else if (dependencyTelemetry.Success == false)
            {
                Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallFailureCount);
            }
        }
        private QuickPulseDataSample CollectSample()
        {
            // For AI data, all we have to do is lock the current accumulator in
            QuickPulseDataAccumulator completeAccumulator = this.dataAccumulatorManager.CompleteCurrentDataAccumulator();

            // For performance collection, we have to read perf samples from Windows
            List <Tuple <PerformanceCounterData, double> > perfData =
                this.performanceCollector.Collect((counterName, e) => QuickPulseEventSource.Log.CounterReadingFailedEvent(e.ToString(), counterName))
                .ToList();

            // For top N CPU, we have to get data from the provider
            IEnumerable <Tuple <string, int> > topCpuData = this.DisableTopCpuProcesses
                                                             ? Enumerable.Empty <Tuple <string, int> >()
                                                             : this.topCpuCollector.GetTopProcessesByCpu(TopCpuCount);

            return(this.CreateDataSample(completeAccumulator, perfData, topCpuData, this.topCpuCollector.AccessDenied));
        }
        public void QuickPulseDataSampleCalculatesAIExceptionsPerSecondCorrectly()
        {
            // ARRANGE
            var accumulator =
                new QuickPulseDataAccumulator(new CollectionConfiguration(EmptyCollectionConfigurationInfo, out this.errors, new ClockMock()))
            {
                StartTimestamp   = this.now,
                EndTimestamp     = this.now.AddSeconds(2),
                AIExceptionCount = 3
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.AreEqual(3.0 / 2, dataSample.AIExceptionsPerSecond);
        }
        public void QuickPulseDataSampleCalculatesAIDependencyCallDurationAveWhenDependencyCallCountIsZeroCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2),
                AIDependencyCallCountAndDurationInTicks =
                    QuickPulseDataAccumulator.EncodeCountAndDuration(0, TimeSpan.FromSeconds(5).Ticks)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary);

            // ASSERT
            Assert.AreEqual(0.0, dataSample.AIDependencyCallDurationAveInMs);
        }
        public void QuickPulseDataSampleCalculatesAIRequestDurationAveWhenRequestCountIsZeroCorrectly()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = this.now,
                EndTimestamp   = this.now.AddSeconds(2),
                AIRequestCountAndDurationInTicks =
                    QuickPulseDataAccumulator.EncodeCountAndDuration(0, TimeSpan.FromSeconds(5).Ticks)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.AreEqual(0.0, dataSample.AIRequestDurationAveInMs);
        }
        public void QuickPulseDataSampleTimestampsItselfCorrectly()
        {
            // ARRANGE
            var timestampStart = this.now;
            var timestampEnd   = this.now.AddSeconds(3);
            var accumulator    =
                new QuickPulseDataAccumulator(new CollectionConfiguration(EmptyCollectionConfigurationInfo, out this.errors, new ClockMock()))
            {
                StartTimestamp = timestampStart,
                EndTimestamp   = timestampEnd
            };

            // ACT
            var dataSample = new QuickPulseDataSample(accumulator, this.dummyDictionary, this.dummyTopCpu, false);

            // ASSERT
            Assert.AreEqual(timestampStart, dataSample.StartTimestamp);
            Assert.AreEqual(timestampEnd, dataSample.EndTimestamp);
        }
        public void QuickPulseDataSampleStoresTopCpuData()
        {
            // ARRANGE
            var accumulator = new QuickPulseDataAccumulator
            {
                StartTimestamp = DateTimeOffset.UtcNow,
                EndTimestamp   = DateTimeOffset.UtcNow.AddSeconds(2)
            };

            // ACT
            var dataSample = new QuickPulseDataSample(
                accumulator,
                this.dummyDictionary,
                new List <Tuple <string, int> >()
            {
                Tuple.Create("Process1", 25)
            },
                false);

            // ASSERT
            Assert.AreEqual("Process1", dataSample.TopCpuData.Single().Item1);
            Assert.AreEqual(25, dataSample.TopCpuData.Single().Item2);
        }
Beispiel #26
0
        /// <summary>
        /// Intercepts telemetry items and updates QuickPulse data when needed.
        /// </summary>
        /// <param name="telemetry">Telemetry item being tracked by AI.</param>
        /// <remarks>This method is performance critical since every AI telemetry item goes through it.</remarks>
        public void Process(ITelemetry telemetry)
        {
            bool letItemThrough = true;

            try
            {
                // filter out QPS requests from dependencies even when we're not collecting (for Pings)
                var dependencyCall = telemetry as DependencyTelemetry;
                if (this.serviceEndpoint != null && dependencyCall != null && !string.IsNullOrWhiteSpace(dependencyCall.Name))
                {
                    if (dependencyCall.Name.IndexOf(this.serviceEndpoint.Host, StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        // this is an HTTP request to QuickPulse service, we don't want to let it through
                        letItemThrough = false;

                        return;
                    }
                }

                if (!this.isCollecting || this.dataAccumulatorManager == null)
                {
                    return;
                }

                // only process items that are going to the instrumentation key that our module is initialized with
                if (this.config != null && !string.IsNullOrWhiteSpace(this.config.InstrumentationKey) && telemetry.Context != null &&
                    string.Equals(telemetry.Context.InstrumentationKey, this.config.InstrumentationKey, StringComparison.OrdinalIgnoreCase))
                {
                    var request   = telemetry as RequestTelemetry;
                    var exception = telemetry as ExceptionTelemetry;

                    if (request != null)
                    {
                        bool success = IsRequestSuccessful(request);

                        long requestCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(1, request.Duration.Ticks);

                        Interlocked.Add(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestCountAndDurationInTicks, requestCountAndDurationInTicks);

                        if (success)
                        {
                            Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestSuccessCount);
                        }
                        else
                        {
                            Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIRequestFailureCount);
                        }
                    }
                    else if (dependencyCall != null)
                    {
                        long dependencyCallCountAndDurationInTicks = QuickPulseDataAccumulator.EncodeCountAndDuration(1, dependencyCall.Duration.Ticks);

                        Interlocked.Add(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallCountAndDurationInTicks, dependencyCallCountAndDurationInTicks);

                        if (dependencyCall.Success == true)
                        {
                            Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallSuccessCount);
                        }
                        else if (dependencyCall.Success == false)
                        {
                            Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIDependencyCallFailureCount);
                        }
                    }
                    else if (exception != null)
                    {
                        Interlocked.Increment(ref this.dataAccumulatorManager.CurrentDataAccumulator.AIExceptionCount);
                    }
                }
            }
            catch (Exception e)
            {
                // whatever happened up there - we don't want to interrupt the chain of processors
                QuickPulseEventSource.Log.UnknownErrorEvent(e.ToInvariantString());
            }
            finally
            {
                if (letItemThrough)
                {
                    this.Next.Process(telemetry);
                }
            }
        }
 private QuickPulseDataSample CreateDataSample(
     QuickPulseDataAccumulator accumulator,
     IEnumerable <Tuple <PerformanceCounterData, float> > perfData)
 {
     return(new QuickPulseDataSample(accumulator, perfData.ToDictionary(tuple => tuple.Item1.ReportAs, tuple => tuple)));
 }