Exemple #1
0
        internal static void FlushImpl()
        {
            foreach (KeyValuePair <int, AggregationSet> aggregationSetPair in aggregationSets)
            {
                if (disposing)
                {
                    return;
                }

                AggregationSet aggregationSet = aggregationSetPair.Value;

                ConcurrentDictionary <int, MetricsBag> aggregations = aggregationSet.RemoveAggregations();
                var periodStartTime = DateTimeOffset.Now.Subtract(AggregateMetricsTelemetryModule.FlushInterval);

                foreach (MetricsBag metricsBag in aggregations.Values)
                {
                    if (disposing)
                    {
                        return;
                    }

                    int registrationKey = aggregationSet.Key;

                    string p1Name = null;
                    string p2Name = null;
                    string p3Name = null;
                    var    percentileCalculation = PercentileCalculation.DoNotCalculate;

                    AggregateMetricProperties metricProperties;
                    if (metricRegistrations.TryGetValue(registrationKey, out metricProperties))
                    {
                        if (metricProperties.P1Name != null)
                        {
                            p1Name = metricProperties.P1Name;
                        }

                        if (metricProperties.P2Name != null)
                        {
                            p2Name = metricProperties.P2Name;
                        }

                        if (metricProperties.P3Name != null)
                        {
                            p3Name = metricProperties.P3Name;
                        }

                        percentileCalculation = metricProperties.PercentileCalculation;
                    }

                    AggregationResult aggregation = metricsBag.CalculateAggregation(percentileCalculation);

                    var metric = new MetricTelemetry(aggregationSet.Name, aggregation.Sum)
                    {
                        Timestamp         = periodStartTime,
                        Count             = aggregation.Count,
                        Min               = aggregation.Min,
                        Max               = aggregation.Max,
                        StandardDeviation = aggregation.StdDev
                    };

                    metric.Context.GetInternalContext().SdkVersion = sdkVersion;

                    metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);

                    if (percentileCalculation != PercentileCalculation.DoNotCalculate)
                    {
                        metric.Properties.Add(Constants.P50Name, aggregation.P50.ToString(CultureInfo.InvariantCulture));
                        MetricTelemetry p50Metric = metric.CreateDerivedMetric(Constants.P50Name, aggregation.P50);
                        p50Metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);
                        aggregationSet.TelemetryClient.TrackMetric(p50Metric);

                        metric.Properties.Add(Constants.P75Name, aggregation.P75.ToString(CultureInfo.InvariantCulture));
                        MetricTelemetry p75Metric = metric.CreateDerivedMetric(Constants.P75Name, aggregation.P75);
                        p75Metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);
                        aggregationSet.TelemetryClient.TrackMetric(p75Metric);

                        metric.Properties.Add(Constants.P90Name, aggregation.P90.ToString(CultureInfo.InvariantCulture));
                        MetricTelemetry p90Metric = metric.CreateDerivedMetric(Constants.P90Name, aggregation.P90);
                        p90Metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);
                        aggregationSet.TelemetryClient.TrackMetric(p90Metric);

                        metric.Properties.Add(Constants.P95Name, aggregation.P95.ToString(CultureInfo.InvariantCulture));
                        MetricTelemetry p95Metric = metric.CreateDerivedMetric(Constants.P95Name, aggregation.P95);
                        p95Metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);
                        aggregationSet.TelemetryClient.TrackMetric(p95Metric);

                        metric.Properties.Add(Constants.P99Name, aggregation.P99.ToString(CultureInfo.InvariantCulture));
                        MetricTelemetry p99Metric = metric.CreateDerivedMetric(Constants.P99Name, aggregation.P99);
                        p99Metric.AddProperties(metricsBag, p1Name, p2Name, p3Name);
                        aggregationSet.TelemetryClient.TrackMetric(p99Metric);
                    }

                    aggregationSet.TelemetryClient.TrackMetric(metric);
                }
            }
        }
Exemple #2
0
        internal AggregationResult CalculateAggregation(PercentileCalculation percentileCalculation = PercentileCalculation.DoNotCalculate)
        {
            if (this.Count == 0)
            {
                return(new AggregationResult());
            }

            // Use sorted enumerables if we need percentiles.
            IEnumerable <double> values;

            if (percentileCalculation == PercentileCalculation.OrderByLargest)
            {
                values = this.OrderBy(i => i);
            }
            else if (percentileCalculation == PercentileCalculation.OrderBySmallest)
            {
                values = this.OrderByDescending(i => i);
            }
            else
            {
                values = this;
            }

            double first = values.First();
            double sum   = 0;
            double min   = first;
            double max   = first;

            int p50Index = 0;
            int p75Index = 0;
            int p90Index = 0;
            int p95Index = 0;
            int p99Index = 0;

            bool shouldCalculatePercentile = percentileCalculation != PercentileCalculation.DoNotCalculate;

            if (shouldCalculatePercentile)
            {
                p50Index = this.GetPercentileNearestIndex(50);
                p75Index = this.GetPercentileNearestIndex(75);
                p90Index = this.GetPercentileNearestIndex(90);
                p95Index = this.GetPercentileNearestIndex(95);
                p99Index = this.GetPercentileNearestIndex(99);
            }

            var aggregation = new AggregationResult()
            {
                Count = this.Count
            };

            int valueIndex = 0;

            foreach (double value in values)
            {
                if (value < min)
                {
                    min = value;
                }
                else if (value > max)
                {
                    max = value;
                }

                sum += value;

                if (shouldCalculatePercentile)
                {
                    // Note: This only works if sample size >= 100 (which we enforce with Constants.PercentileMinimumCount).
                    if (valueIndex == p50Index)
                    {
                        aggregation.P50 = value;
                    }
                    else if (valueIndex == p75Index)
                    {
                        aggregation.P75 = value;
                    }
                    else if (valueIndex == p90Index)
                    {
                        aggregation.P90 = value;
                    }
                    else if (valueIndex == p95Index)
                    {
                        aggregation.P95 = value;
                    }
                    else if (valueIndex == p99Index)
                    {
                        aggregation.P99 = value;
                    }
                }

                valueIndex++;
            }

            aggregation.Sum = sum;
            aggregation.Min = min;
            aggregation.Max = max;

            aggregation.StdDev = Math.Sqrt(this.Average(v => Math.Pow(v - aggregation.Average, 2)));

            return(aggregation);
        }