public void DefaultState() { DateTimeOffset dto = new DateTimeOffset(2017, 10, 2, 17, 5, 0, TimeSpan.FromHours(-7)); var aggregationManager = new MetricAggregationManager(); var measurementMetric = new MetricSeries( aggregationManager, "Measurement Metric", null, new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false)); var accumulatorMetric = new MetricSeries( aggregationManager, "Accumulator Metric", null, new MetricSeriesConfigurationForAccumulator(restrictToUInt32Values: false)); measurementMetric.TrackValue(1); accumulatorMetric.TrackValue(2); AggregationPeriodSummary defaultPeriod = aggregationManager.StartOrCycleAggregators(MetricAggregationCycleKind.Default, dto, futureFilter: null); Assert.IsNotNull(defaultPeriod); Assert.IsNotNull(defaultPeriod.NonpersistentAggregates); Assert.IsNotNull(defaultPeriod.PersistentAggregates); Assert.AreEqual(1, defaultPeriod.NonpersistentAggregates.Count); Assert.AreEqual("Measurement Metric", (defaultPeriod.NonpersistentAggregates[0]).MetricId); Assert.AreEqual(1, defaultPeriod.NonpersistentAggregates[0].Data["Count"]); Assert.AreEqual(1.0, defaultPeriod.NonpersistentAggregates[0].Data["Sum"]); Assert.AreEqual(1, defaultPeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", defaultPeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, defaultPeriod.PersistentAggregates[0].Data["Sum"]); AggregationPeriodSummary customPeriod = aggregationManager.StartOrCycleAggregators(MetricAggregationCycleKind.Custom, dto, futureFilter: null); Assert.IsNotNull(customPeriod); Assert.IsNotNull(customPeriod.NonpersistentAggregates); Assert.IsNotNull(customPeriod.PersistentAggregates); Assert.AreEqual(0, customPeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, customPeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", customPeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, customPeriod.PersistentAggregates[0].Data["Sum"]); AggregationPeriodSummary quickpulsePeriod = aggregationManager.StartOrCycleAggregators(MetricAggregationCycleKind.QuickPulse, dto, futureFilter: null); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(0, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, quickpulsePeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", quickpulsePeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, quickpulsePeriod.PersistentAggregates[0].Data["Sum"]); }
public void CreateAggregateUnsafe() { var aggregationManager = new MetricAggregationManager(); var seriesConfig = new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: true); IEnumerable <KeyValuePair <string, string> > setDimensionNamesValues = new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("Dim 1", "DV1"), new KeyValuePair <string, string>("Dim 2", "DV2"), new KeyValuePair <string, string>("Dim 3", "DV3"), new KeyValuePair <string, string>("Dim 2", "DV2a") }; IEnumerable <KeyValuePair <string, string> > expectedDimensionNamesValues = new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("Dim 1", "DV1"), new KeyValuePair <string, string>("Dim 2", "DV2a"), new KeyValuePair <string, string>("Dim 3", "DV3") }; var metric = new MetricSeries( aggregationManager, new MetricIdentifier(String.Empty, "Cows Sold", expectedDimensionNamesValues.Select(nv => nv.Key).ToArray()), setDimensionNamesValues, seriesConfig); var aggregator = new MeasurementAggregator( (MetricSeriesConfigurationForMeasurement)metric.GetConfiguration(), metric, CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.CreateAggregateUnsafe(aggregator, metric, expectedDimensionNamesValues); }
/// <summary> /// /// </summary> /// <param name="telemetryPipeline"></param> public MetricManager(IMetricTelemetryPipeline telemetryPipeline) { Util.ValidateNotNull(telemetryPipeline, nameof(telemetryPipeline)); _telemetryPipeline = telemetryPipeline; _aggregationManager = new MetricAggregationManager(); _aggregationCycle = new DefaultAggregationPeriodCycle(_aggregationManager, this); _aggregationCycle.Start(); }
internal MetricSeries( MetricAggregationManager aggregationManager, string metricId, IEnumerable <KeyValuePair <string, string> > dimensionNamesAndValues, IMetricSeriesConfiguration configuration) { Util.ValidateNotNull(aggregationManager, nameof(aggregationManager)); Util.ValidateNotNull(metricId, nameof(metricId)); Util.ValidateNotNull(configuration, nameof(configuration)); _aggregationManager = aggregationManager; _metricId = metricId; _configuration = configuration; _requiresPersistentAggregator = configuration.RequiresPersistentAggregation; var dimNameVals = new Dictionary <string, string>(); if (dimensionNamesAndValues != null) { int dimIndex = 0; foreach (KeyValuePair <string, string> dimNameVal in dimensionNamesAndValues) { if (dimNameVal.Key == null) { throw new ArgumentNullException($"The name for dimension at 0-based index '{dimIndex}' is null."); } if (String.IsNullOrWhiteSpace(dimNameVal.Key)) { throw new ArgumentException($"The name for dimension at 0-based index '{dimIndex}' is empty or white-space"); } if (dimNameVal.Value == null) { throw new ArgumentNullException($"The value for dimension '{dimNameVal.Key}' number is null."); } if (String.IsNullOrWhiteSpace(dimNameVal.Value)) { throw new ArgumentNullException($"The value for dimension '{dimNameVal.Key}' is empty or white-space."); } dimNameVals[dimNameVal.Key] = dimNameVal.Value; dimIndex++; } } _dimensionNamesAndValues = dimNameVals; _aggregatorPersistent = null; _aggregatorDefault = null; _aggregatorQuickPulse = null; _aggregatorCustom = null; }
public DefaultAggregationPeriodCycle(MetricAggregationManager aggregationManager, MetricManager metricManager) { Util.ValidateNotNull(aggregationManager, nameof(aggregationManager)); Util.ValidateNotNull(metricManager, nameof(metricManager)); this.aggregationManager = aggregationManager; this.metricManager = metricManager; this.runningState = RunningState_NotStarted; this.workerTaskCompletionControl = new TaskCompletionSource <bool>(); this.aggregationThread = null; }
public void CreateAggregateUnsafe() { var aggregationManager = new MetricAggregationManager(); var seriesConfig = new MetricSeriesConfigurationForNaiveDistinctCount(usePersistentAggregation: false); var metric = new MetricSeries( aggregationManager, new MetricIdentifier(null, "Distinct Cows Sold", "Dim 2", "Dim 3", "Dim 1"), new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("Dim 1", "DV1"), new KeyValuePair <string, string>("Dim 2", "DV2"), new KeyValuePair <string, string>("Dim 3", "DV3"), new KeyValuePair <string, string>("Dim 2", "DV2a") }, seriesConfig); var aggregator = new NaiveDistinctCountMetricSeriesAggregator( (MetricSeriesConfigurationForNaiveDistinctCount)metric.GetConfiguration(), metric, CycleKind.Custom); var startTS = new DateTimeOffset(2017, 9, 25, 17, 0, 0, TimeSpan.FromHours(-8)); var endTS = new DateTimeOffset(2017, 9, 25, 17, 1, 0, TimeSpan.FromHours(-8)); aggregator.Reset(startTS, valueFilter: null); aggregator.TrackValue("Foo"); aggregator.TrackValue("Bar"); aggregator.TrackValue("Foo"); MetricAggregate aggregate = aggregator.CreateAggregateUnsafe(endTS); Assert.IsNotNull(aggregate); Assert.AreEqual("Distinct Cows Sold", aggregate.MetricId, "aggregate.MetricId mismatch"); Assert.AreEqual(3, aggregate.Data["TotalCount"], "aggregate.Data[TotalCount] mismatch"); Assert.AreEqual(2, aggregate.Data["DistinctCount"], "aggregate.Data[DistinctCount] mismatch"); Assert.AreEqual(startTS, aggregate.AggregationPeriodStart, "metricAggregate.Timestamp mismatch"); Assert.AreEqual( (endTS - startTS).TotalMilliseconds, aggregate.AggregationPeriodDuration.TotalMilliseconds, "aggregate.AggregationPeriodDuration mismatch"); Assert.AreEqual(3, aggregate.Dimensions.Count); Assert.IsTrue(aggregate.Dimensions.ContainsKey("Dim 1")); Assert.AreEqual("DV1", aggregate.Dimensions["Dim 1"]); Assert.IsTrue(aggregate.Dimensions.ContainsKey("Dim 2")); Assert.AreEqual("DV2a", aggregate.Dimensions["Dim 2"]); Assert.IsTrue(aggregate.Dimensions.ContainsKey("Dim 3")); Assert.AreEqual("DV3", aggregate.Dimensions["Dim 3"]); }
public void StartOrCycleAggregators() { StartOrCycleAggregatorsTest(MetricAggregationCycleKind.Default, supportsSettingFilters: false); StartOrCycleAggregatorsTest(MetricAggregationCycleKind.QuickPulse, supportsSettingFilters: true); StartOrCycleAggregatorsTest(MetricAggregationCycleKind.Custom, supportsSettingFilters: true); { DateTimeOffset dto = new DateTimeOffset(2017, 10, 2, 17, 5, 0, TimeSpan.FromHours(-7)); var aggregationManager = new MetricAggregationManager(); Assert.ThrowsException <ArgumentException>(() => aggregationManager.StartOrCycleAggregators((MetricAggregationCycleKind)42, dto, futureFilter: null)); } }
public DefaultAggregationPeriodCycle(MetricAggregationManager aggregationManager, MetricManager metricManager) { Util.ValidateNotNull(aggregationManager, nameof(aggregationManager)); Util.ValidateNotNull(metricManager, nameof(metricManager)); _workerMethod = this.Run; _aggregationManager = aggregationManager; _metricManager = metricManager; _runningState = RunningState_NotStarted; _workerTask = null; }
public void CompleteAggregation() { var aggregationManager = new MetricAggregationManager(); var mesurementConfig = new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: true); var measurementMetric = new MetricSeries(aggregationManager, new MetricIdentifier("Cows Sold"), null, mesurementConfig); var measurementAggregator = new MeasurementAggregator( (MetricSeriesConfigurationForMeasurement)measurementMetric.GetConfiguration(), measurementMetric, CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.CompleteAggregation_NonpersistentAggregator(measurementAggregator); }
public void GetDataSeries() { var aggregationManager = new MetricAggregationManager(); var seriesConfig = new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: true); var metric = new MetricSeries(aggregationManager, new MetricIdentifier("Cows Sold"), null, seriesConfig); var aggregatorForConcreteSeries = new MeasurementAggregator( (MetricSeriesConfigurationForMeasurement)metric.GetConfiguration(), dataSeries: metric, aggregationCycleKind: CycleKind.Custom); var aggregatorForNullSeries = new MeasurementAggregator( new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: true), dataSeries: null, aggregationCycleKind: CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.GetDataSeries(aggregatorForConcreteSeries, aggregatorForNullSeries, metric); }
public void GetDataSeries() { var aggregationManager = new MetricAggregationManager(); var seriesConfig = new MetricSeriesConfigurationForNaiveDistinctCount(usePersistentAggregation: false); var metric = new MetricSeries(aggregationManager, new MetricIdentifier("Cows Sold"), null, seriesConfig); var aggregatorForConcreteSeries = new NaiveDistinctCountMetricSeriesAggregator( (MetricSeriesConfigurationForNaiveDistinctCount)metric.GetConfiguration(), dataSeries: metric, aggregationCycleKind: CycleKind.Custom); var aggregatorForNullSeries = new NaiveDistinctCountMetricSeriesAggregator( new MetricSeriesConfigurationForNaiveDistinctCount(usePersistentAggregation: false), dataSeries: null, aggregationCycleKind: CycleKind.Custom); Assert.IsNotNull(aggregatorForConcreteSeries.DataSeries); Assert.AreSame(metric, aggregatorForConcreteSeries.DataSeries); Assert.IsNull(aggregatorForNullSeries.DataSeries); }
public void CompleteAggregation() { var aggregationManager = new MetricAggregationManager(); var mesurementConfig = new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false); var measurementMetric = new MetricSeries(aggregationManager, new MetricIdentifier("Animal Metrics", "Cows Sold"), null, mesurementConfig); var measurementAggregator = new MeasurementAggregator( (MetricSeriesConfigurationForMeasurement)measurementMetric.GetConfiguration(), measurementMetric, CycleKind.Custom); var accumulatorConfig = new MetricSeriesConfigurationForTestingAccumulatorBehavior(); var accumulatorMetric = new MetricSeries(aggregationManager, new MetricIdentifier("Animal Metrics", "Cows Sold"), null, accumulatorConfig); var accumulatorAggregator = new MetricSeriesConfigurationForTestingAccumulatorBehavior.Aggregator( (MetricSeriesConfigurationForTestingAccumulatorBehavior)accumulatorMetric.GetConfiguration(), accumulatorMetric, CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.CompleteAggregation_NonpersistentAggregator(measurementAggregator); CommonSimpleDataSeriesAggregatorTests.CompleteAggregation_PersistentAggregator(accumulatorAggregator); }
public void CompleteAggregation() { var aggregationManager = new MetricAggregationManager(); var mesurementConfig = new SimpleMetricSeriesConfiguration(restrictToUInt32Values: false); var measurementMetric = new MetricSeries(aggregationManager, "Cows Sold", null, mesurementConfig); var measurementAggregator = new MeasurementAggregator( (SimpleMetricSeriesConfiguration)measurementMetric.GetConfiguration(), measurementMetric, CycleKind.Custom); var accumulatorConfig = new AccumulatorMetricSeriesConfiguration(restrictToUInt32Values: false); var accumulatorMetric = new MetricSeries(aggregationManager, "Cows Sold", null, accumulatorConfig); var accumulatorAggregator = new AccumulatorAggregator( (AccumulatorMetricSeriesConfiguration)accumulatorMetric.GetConfiguration(), accumulatorMetric, CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.CompleteAggregation_NonpersistentAggregator(measurementAggregator); CommonSimpleDataSeriesAggregatorTests.CompleteAggregation_PersistentAggregator(accumulatorAggregator); }
public void CreateAggregateUnsafe() { var aggregationManager = new MetricAggregationManager(); var seriesConfig = new SimpleMetricSeriesConfiguration(restrictToUInt32Values: false); IEnumerable <KeyValuePair <string, string> > setDimensionNamesValues = new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("Dim 1", "DV1"), new KeyValuePair <string, string>("Dim 2", "DV2"), new KeyValuePair <string, string>("Dim 3", "DV3"), new KeyValuePair <string, string>("Dim 2", "DV2a") }; IEnumerable <KeyValuePair <string, string> > expectedDimensionNamesValues = new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("Dim 1", "DV1"), new KeyValuePair <string, string>("Dim 2", "DV2a"), new KeyValuePair <string, string>("Dim 3", "DV3") }; var metric = new MetricSeries(aggregationManager, "Cows Sold", setDimensionNamesValues, seriesConfig); var aggregator = new MeasurementAggregator( (SimpleMetricSeriesConfiguration)metric.GetConfiguration(), metric, CycleKind.Custom); CommonSimpleDataSeriesAggregatorTests.CreateAggregateUnsafe(aggregator, metric, expectedDimensionNamesValues); }
public void StopAggregators() { DateTimeOffset dto = new DateTimeOffset(2017, 10, 2, 17, 5, 0, TimeSpan.FromHours(-7)); var aggregationManager = new MetricAggregationManager(); var measurementMetric = new MetricSeries( aggregationManager, "Measurement Metric", null, new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false)); var accumulatorMetric = new MetricSeries( aggregationManager, "Accumulator Metric", null, new MetricSeriesConfigurationForAccumulator(restrictToUInt32Values: false)); // Cannot stop default: Assert.ThrowsException <ArgumentException>(() => aggregationManager.StopAggregators(MetricAggregationCycleKind.Default, dto)); // Stop cycles that never started: AggregationPeriodSummary customPeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.Custom, dto); Assert.IsNotNull(customPeriod); Assert.IsNotNull(customPeriod.NonpersistentAggregates); Assert.IsNotNull(customPeriod.PersistentAggregates); Assert.AreEqual(0, customPeriod.NonpersistentAggregates.Count); Assert.AreEqual(0, customPeriod.PersistentAggregates.Count); AggregationPeriodSummary quickpulsePeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.QuickPulse, dto); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(0, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual(0, quickpulsePeriod.PersistentAggregates.Count); // Track a value. Stop cycles that never started again. Observe that persistent cycle was active by default: measurementMetric.TrackValue(1); accumulatorMetric.TrackValue(2); customPeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.Custom, dto); Assert.IsNotNull(customPeriod); Assert.IsNotNull(customPeriod.NonpersistentAggregates); Assert.IsNotNull(customPeriod.PersistentAggregates); Assert.AreEqual(0, customPeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, customPeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", customPeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, customPeriod.PersistentAggregates[0].Data["Sum"]); quickpulsePeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.QuickPulse, dto); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(0, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, quickpulsePeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", quickpulsePeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, quickpulsePeriod.PersistentAggregates[0].Data["Sum"]); // Now start cycles, track values and stop them again. Observe that values were tracked: aggregationManager.StartOrCycleAggregators(MetricAggregationCycleKind.Custom, dto, futureFilter: null); aggregationManager.StartOrCycleAggregators(MetricAggregationCycleKind.QuickPulse, dto, futureFilter: null); measurementMetric.TrackValue(3); accumulatorMetric.TrackValue(4); customPeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.Custom, dto); Assert.IsNotNull(customPeriod); Assert.IsNotNull(customPeriod.NonpersistentAggregates); Assert.IsNotNull(customPeriod.PersistentAggregates); Assert.AreEqual(1, customPeriod.NonpersistentAggregates.Count); Assert.AreEqual("Measurement Metric", customPeriod.NonpersistentAggregates[0].MetricId); Assert.AreEqual(1, customPeriod.NonpersistentAggregates[0].Data["Count"]); Assert.AreEqual(3.0, customPeriod.NonpersistentAggregates[0].Data["Sum"]); Assert.AreEqual(1, customPeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", customPeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(6.0, customPeriod.PersistentAggregates[0].Data["Sum"]); quickpulsePeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.QuickPulse, dto); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(1, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual("Measurement Metric", quickpulsePeriod.NonpersistentAggregates[0].MetricId); Assert.AreEqual(1, quickpulsePeriod.NonpersistentAggregates[0].Data["Count"]); Assert.AreEqual(3.0, quickpulsePeriod.NonpersistentAggregates[0].Data["Sum"]); Assert.AreEqual(1, quickpulsePeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", quickpulsePeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(6.0, quickpulsePeriod.PersistentAggregates[0].Data["Sum"]); measurementMetric.TrackValue(5); accumulatorMetric.TrackValue(6); quickpulsePeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.Custom, dto); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(0, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, customPeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", customPeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(6.0, customPeriod.PersistentAggregates[0].Data["Sum"]); quickpulsePeriod = aggregationManager.StopAggregators(MetricAggregationCycleKind.QuickPulse, dto); Assert.IsNotNull(quickpulsePeriod); Assert.IsNotNull(quickpulsePeriod.NonpersistentAggregates); Assert.IsNotNull(quickpulsePeriod.PersistentAggregates); Assert.AreEqual(0, quickpulsePeriod.NonpersistentAggregates.Count); Assert.AreEqual(1, quickpulsePeriod.PersistentAggregates.Count); Assert.AreEqual("Accumulator Metric", quickpulsePeriod.PersistentAggregates[0].MetricId); Assert.AreEqual(12.0, quickpulsePeriod.PersistentAggregates[0].Data["Sum"]); }
public void Ctor() { var aggregationManager = new MetricAggregationManager(); Assert.IsNotNull(aggregationManager); }
private static void StartOrCycleAggregatorsTest(MetricAggregationCycleKind cycleKind, bool supportsSettingFilters) { DateTimeOffset dto = new DateTimeOffset(2017, 10, 2, 17, 5, 0, TimeSpan.FromHours(-7)); var aggregationManager = new MetricAggregationManager(); var measurementMetric = new MetricSeries( aggregationManager, "Measurement Metric", null, new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false)); var accumulatorMetric = new MetricSeries( aggregationManager, "Accumulator Metric", null, new MetricSeriesConfigurationForAccumulator(restrictToUInt32Values: false)); // Cycle once, get nothing: AggregationPeriodSummary period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(0, period.NonpersistentAggregates.Count); Assert.AreEqual(0, period.PersistentAggregates.Count); // Record something, cycle, check for it: measurementMetric.TrackValue(1); accumulatorMetric.TrackValue(2); period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(1, period.NonpersistentAggregates.Count); Assert.AreEqual(1, period.PersistentAggregates.Count); Assert.IsNotNull(period.NonpersistentAggregates[0]); Assert.IsNotNull(period.PersistentAggregates[0]); Assert.AreEqual("Measurement Metric", period.NonpersistentAggregates[0].MetricId); Assert.AreEqual(1, period.NonpersistentAggregates[0].Data["Count"]); Assert.AreEqual(1.0, period.NonpersistentAggregates[0].Data["Sum"]); Assert.AreEqual("Accumulator Metric", period.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, period.PersistentAggregates[0].Data["Sum"]); // Now we should be empty again for non-persistent. Persistent stays: period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(0, period.NonpersistentAggregates.Count); Assert.AreEqual(1, period.PersistentAggregates.Count); Assert.IsNotNull(period.PersistentAggregates[0]); Assert.AreEqual("Accumulator Metric", period.PersistentAggregates[0].MetricId); Assert.AreEqual(2.0, period.PersistentAggregates[0].Data["Sum"]); // Now set a deny filter. Track. Expect to get nothng. // Note: for persistent, values tracked under Deny filter should persist for the future, for non-persistent they are just discarded. if (false == supportsSettingFilters) { Assert.ThrowsException <ArgumentException>(() => aggregationManager.StartOrCycleAggregators( cycleKind, dto, futureFilter: new AcceptAllFilter())); } else { period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: new DenyAllFilter()); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); measurementMetric.TrackValue(3); accumulatorMetric.TrackValue(4); period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(0, period.NonpersistentAggregates.Count); Assert.AreEqual(0, period.PersistentAggregates.Count); period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(0, period.NonpersistentAggregates.Count); Assert.AreEqual(1, period.PersistentAggregates.Count); Assert.IsNotNull(period.PersistentAggregates[0]); Assert.AreEqual("Accumulator Metric", period.PersistentAggregates[0].MetricId); Assert.AreEqual(6.0, period.PersistentAggregates[0].Data["Sum"]); // Validate that deny filter was removed: measurementMetric.TrackValue(5); accumulatorMetric.TrackValue(6); period = aggregationManager.StartOrCycleAggregators(cycleKind, dto, futureFilter: null); Assert.IsNotNull(period); Assert.IsNotNull(period.NonpersistentAggregates); Assert.IsNotNull(period.PersistentAggregates); Assert.AreEqual(1, period.NonpersistentAggregates.Count); Assert.AreEqual(1, period.PersistentAggregates.Count); Assert.IsNotNull(period.PersistentAggregates[0]); Assert.IsNotNull(period.NonpersistentAggregates[0]); Assert.AreEqual("Accumulator Metric", period.PersistentAggregates[0].MetricId); Assert.AreEqual(12.0, period.PersistentAggregates[0].Data["Sum"]); Assert.AreEqual("Measurement Metric", period.NonpersistentAggregates[0].MetricId); Assert.AreEqual(5.0, period.NonpersistentAggregates[0].Data["Sum"]); } }
internal MetricSeries( MetricAggregationManager aggregationManager, MetricIdentifier metricIdentifier, IEnumerable <KeyValuePair <string, string> > dimensionNamesAndValues, IMetricSeriesConfiguration configuration) { // Validate and store aggregationManager: Util.ValidateNotNull(aggregationManager, nameof(aggregationManager)); this.aggregationManager = aggregationManager; // Validate and store metricIdentifier: Util.ValidateNotNull(metricIdentifier, nameof(metricIdentifier)); this.MetricIdentifier = metricIdentifier; // Copy dimensionNamesAndValues, validate values (keys are implicitly validated as they need to match the keys in the identifier): var dimNameVals = new Dictionary <string, string>(); if (dimensionNamesAndValues != null) { int dimIndex = 0; foreach (KeyValuePair <string, string> dimNameVal in dimensionNamesAndValues) { if (dimNameVal.Value == null) { throw new ArgumentNullException(Invariant($"The value for dimension '{dimNameVal.Key}' number is null.")); } if (String.IsNullOrWhiteSpace(dimNameVal.Value)) { throw new ArgumentNullException(Invariant($"The value for dimension '{dimNameVal.Key}' is empty or white-space.")); } dimNameVals[dimNameVal.Key] = dimNameVal.Value; dimIndex++; } } // Validate that metricIdentifier and dimensionNamesAndValues contain consistent dimension names: if (metricIdentifier.DimensionsCount != dimNameVals.Count) { throw new ArgumentException(Invariant($"The specified {nameof(metricIdentifier)} contains {metricIdentifier.DimensionsCount} dimensions,") + Invariant($" however the specified {nameof(dimensionNamesAndValues)} contains {dimNameVals.Count} name-value pairs with unique names.")); } foreach (string dimName in metricIdentifier.GetDimensionNames()) { if (false == dimNameVals.ContainsKey(dimName)) { throw new ArgumentException(Invariant($"The specified {nameof(metricIdentifier)} contains a dimension named \"{dimName}\",") + Invariant($" however the specified {nameof(dimensionNamesAndValues)} does not contain an entry for that name.")); } } // Store copied dimensionNamesAndValues: this.dimensionNamesAndValues = dimNameVals; // Validate and store configuration: Util.ValidateNotNull(configuration, nameof(configuration)); this.configuration = configuration; this.requiresPersistentAggregator = configuration.RequiresPersistentAggregation; // Init other instance vars: this.aggregatorPersistent = null; this.aggregatorDefault = null; this.aggregatorQuickPulse = null; this.aggregatorCustom = null; }
public void CompleteAggregation() { var aggregationManager = new MetricAggregationManager(); var nonPersistentConfig = new MetricSeriesConfigurationForNaiveDistinctCount(usePersistentAggregation: false); var nonPersistentMetric = new MetricSeries(aggregationManager, new MetricIdentifier("Unique Cows Sold"), null, nonPersistentConfig); var nonPersistentAggregator = new NaiveDistinctCountMetricSeriesAggregator( (MetricSeriesConfigurationForNaiveDistinctCount)nonPersistentMetric.GetConfiguration(), nonPersistentMetric, CycleKind.Custom); var persistentConfig = new MetricSeriesConfigurationForNaiveDistinctCount(usePersistentAggregation: true); var persistentMetric = new MetricSeries(aggregationManager, new MetricIdentifier("Unique Cows Sold"), null, persistentConfig); var persistentAggregator = new NaiveDistinctCountMetricSeriesAggregator( (MetricSeriesConfigurationForNaiveDistinctCount)persistentMetric.GetConfiguration(), persistentMetric, CycleKind.Custom); var startTS = new DateTimeOffset(2017, 9, 25, 17, 0, 0, TimeSpan.FromHours(-8)); var endTS = new DateTimeOffset(2017, 9, 25, 17, 1, 0, TimeSpan.FromHours(-8)); long periodMillis = (long)(endTS - startTS).TotalMilliseconds; int filterDoubleInvocationsCount = 0; int filterObjectInvocationsCount = 0; nonPersistentAggregator.Reset( startTS, new CommonSimpleDataSeriesAggregatorTests.CustomDoubleValueFilter( filterFunctionDouble: (s, v) => { filterDoubleInvocationsCount++; return(true); }, filterFunctionObject: (s, v) => { filterObjectInvocationsCount++; return(true); })); Assert.AreEqual(0, filterDoubleInvocationsCount); Assert.AreEqual(0, filterObjectInvocationsCount); nonPersistentAggregator.TrackValue(1); nonPersistentAggregator.TrackValue("2"); nonPersistentAggregator.TrackValue(2); MetricAggregate aggregate = nonPersistentAggregator.CompleteAggregation(endTS); ValidateNumericAggregateValues(aggregate, name: "Unique Cows Sold", count: 3, sum: 2, max: 0, min: 0, stdDev: 0, timestamp: startTS, periodMs: periodMillis); Assert.AreEqual(2, filterDoubleInvocationsCount); Assert.AreEqual(1, filterObjectInvocationsCount); nonPersistentAggregator.TrackValue("3"); nonPersistentAggregator.TrackValue(4); aggregate = nonPersistentAggregator.CompleteAggregation(endTS); //// We had this originally when completed agregators did not take any more values when they were non-persistent. This complexity has no benefit. //ValidateNumericAggregateValues(aggregate, name: "Unique Cows Sold", count: 3, sum: 2, max: 0, min: 0, stdDev: 0, timestamp: startTS, periodMs: periodMillis); //Assert.AreEqual(2, filterDoubleInvocationsCount); //Assert.AreEqual(1, filterObjectInvocationsCount); ValidateNumericAggregateValues(aggregate, name: "Unique Cows Sold", count: 5, sum: 4, max: 0, min: 0, stdDev: 0, timestamp: startTS, periodMs: periodMillis); Assert.AreEqual(3, filterDoubleInvocationsCount); Assert.AreEqual(2, filterObjectInvocationsCount); filterDoubleInvocationsCount = 0; filterObjectInvocationsCount = 0; persistentAggregator.Reset( startTS, new CommonSimpleDataSeriesAggregatorTests.CustomDoubleValueFilter( filterFunctionDouble: (s, v) => { filterDoubleInvocationsCount++; return(true); }, filterFunctionObject: (s, v) => { filterObjectInvocationsCount++; return(true); })); Assert.AreEqual(0, filterDoubleInvocationsCount); Assert.AreEqual(0, filterObjectInvocationsCount); persistentAggregator.TrackValue(1); persistentAggregator.TrackValue("2"); persistentAggregator.TrackValue("1"); aggregate = persistentAggregator.CompleteAggregation(endTS); ValidateNumericAggregateValues(aggregate, name: "Unique Cows Sold", count: 3, sum: 2, max: 0, min: 0, stdDev: 0, timestamp: startTS, periodMs: periodMillis); Assert.AreEqual(1, filterDoubleInvocationsCount); Assert.AreEqual(2, filterObjectInvocationsCount); persistentAggregator.TrackValue("3"); persistentAggregator.TrackValue(4); aggregate = persistentAggregator.CompleteAggregation(endTS); ValidateNumericAggregateValues(aggregate, name: "Unique Cows Sold", count: 5, sum: 4, max: 0, min: 0, stdDev: 0, timestamp: startTS, periodMs: periodMillis); Assert.AreEqual(2, filterDoubleInvocationsCount); Assert.AreEqual(3, filterObjectInvocationsCount); }