public override IList <Metric> CreateMetrics(IViewData viewData, IAggregationData aggregation, TagValues tagValues, long timeStamp) { List <Metric> results = new List <Metric>(); var unit = viewData.View.Measure.Unit; var tags = GetTagKeysAndValues(viewData.View.Columns, tagValues.Values); var name = viewData.View.Name.AsString; aggregation.Match <object>( (arg) => { results.Add(new Metric(GetMetricName(name, string.Empty, tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Sum)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, string.Empty, tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Sum)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, string.Empty, tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Count)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, string.Empty, tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Mean)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, string.Empty, tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Mean)); results.Add(new Metric(GetMetricName(name, "max", tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Max)); results.Add(new Metric(GetMetricName(name, "min", tags), MetricType.GAUGE, timeStamp, unit, tags, arg.Min)); var stdDeviation = Math.Sqrt((arg.SumOfSquaredDeviations / arg.Count) - 1); if (double.IsNaN(stdDeviation)) { stdDeviation = 0.0; } results.Add(new Metric(GetMetricName(name, "stddev", tags), MetricType.GAUGE, timeStamp, unit, tags, stdDeviation)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, "value", tags), MetricType.GAUGE, timeStamp, unit, tags, arg.LastValue)); return(null); }, (arg) => { results.Add(new Metric(GetMetricName(name, "value", tags), MetricType.GAUGE, timeStamp, unit, tags, arg.LastValue)); return(null); }, (arg) => { return(null); }); return(results); }
public static TypedValue CreateTypedValue( IAggregation aggregation, IAggregationData aggregationData) { return(aggregationData.Match( v => new TypedValue { DoubleValue = v.Sum }, // Double v => new TypedValue { Int64Value = v.Sum }, // Long v => new TypedValue { Int64Value = v.Count }, // Count v => new TypedValue { DoubleValue = v.Count }, // Mean v => new TypedValue { DistributionValue = CreateDistribution(v, ((IDistribution)aggregation).BucketBoundaries) }, // Distribution v => new TypedValue { DoubleValue = v.LastValue }, // LastValue Double v => new TypedValue { Int64Value = v.LastValue }, // LastValue Long v => new TypedValue { BoolValue = false })); // Default }
internal static void AssertAggregationDataEquals( IAggregationData expected, IAggregationData actual, double tolerance) { expected.Match <object>( (arg) => { Assert.IsType <SumDataDouble>(actual); Assert.InRange(((SumDataDouble)actual).Sum, arg.Sum - tolerance, arg.Sum + tolerance); return(null); }, (arg) => { Assert.IsType <SumDataLong>(actual); Assert.InRange(((SumDataLong)actual).Sum, arg.Sum - tolerance, arg.Sum + tolerance); return(null); }, (arg) => { Assert.IsType <CountData>(actual); Assert.Equal(arg.Count, ((CountData)actual).Count); return(null); }, (arg) => { Assert.IsType <MeanData>(actual); Assert.InRange(((MeanData)actual).Mean, arg.Mean - tolerance, arg.Mean + tolerance); return(null); }, (arg) => { Assert.IsType <DistributionData>(actual); AssertDistributionDataEquals(arg, (IDistributionData)actual, tolerance); return(null); }, (arg) => { Assert.IsType <LastValueDataDouble>(actual); Assert.InRange(((LastValueDataDouble)actual).LastValue, arg.LastValue - tolerance, arg.LastValue + tolerance); return(null); }, (arg) => { Assert.IsType <LastValueDataLong>(actual); Assert.Equal(arg.LastValue, ((LastValueDataLong)actual).LastValue); return(null); }, (arg) => { throw new ArgumentException(); }); }
private static Point ExtractPointInInterval( System.DateTimeOffset startTime, System.DateTimeOffset endTime, IAggregation aggregation, IAggregationData points) { return(new Point { Value = CreateTypedValue(aggregation, points), Interval = CreateTimeInterval(startTime, endTime), }); }
private static Point ExtractPointInInterval( ITimestamp startTime, ITimestamp endTime, IAggregation aggregation, IAggregationData points) { return(new Point { Value = CreateTypedValue(aggregation, points), Interval = CreateTimeInterval(startTime, endTime) }); }
protected internal List <MetricSample> GetMetricMeasurements(IViewData viewData, List <KeyValuePair <string, string> > tags) { var tagValues = GetTagValuesInColumnOrder(viewData.View.Columns, tags); if (tagValues == null) { // One or more of tag keys are invalid return(new List <MetricSample>()); } IAggregationData agg = MetricsHelpers.SumWithTags(viewData, tagValues); return(GetMetricSamples(agg, viewData)); }
public PrometheusMetricValueBuilder WithValue(IAggregationData metric) { // TODO: review conversions // counter, gauge, histogram, summary, or untyped if (metric is ISumDataDouble doubleSum) { this.Value = doubleSum.Sum; } else if (metric is ISumDataLong longSum) { this.Value = longSum.Sum; } else if (metric is ICountData count) { this.Value = count.Count; } else if (metric is IMeanData mean) { // TODO: do more with this this.Value = mean.Mean; } else if (metric is IDistributionData dist) { // TODO: do more with this this.Value = dist.Mean; } else if (metric is ILastValueDataDouble lastDoubleValue) { this.Value = lastDoubleValue.LastValue; } else if (metric is ILastValueDataLong lastLongValue) { this.Value = lastLongValue.LastValue; } else if (metric is IAggregationData aggregationData) { // TODO: report an error } return(this); }
/// <summary> /// Convert ViewData to a list of TimeSeries, so that ViewData can be uploaded to Stackdriver. /// </summary> /// <param name="viewData">OpenTelemetry View</param> /// <param name="metricDescriptor">Stackdriver Metric Descriptor</param> /// <param name="monitoredResource">Stackdriver Resource to which the metrics belong</param> /// <param name="domain">The metrics domain (namespace)</param> /// <returns></returns> public static List <TimeSeries> CreateTimeSeriesList( IViewData viewData, MonitoredResource monitoredResource, MetricDescriptor metricDescriptor, string domain) { var timeSeriesList = new List <TimeSeries>(); if (viewData == null) { return(timeSeriesList); } IView view = viewData.View; var startTime = viewData.Start.ToTimestamp(); // Each entry in AggregationMap will be converted into an independent TimeSeries object foreach (var entry in viewData.AggregationMap) { var timeSeries = new TimeSeries(); IReadOnlyList <TagValue> labels = entry.Key.Values; IAggregationData points = entry.Value; timeSeries.Resource = monitoredResource; timeSeries.ValueType = view.Measure.ToValueType(view.Aggregation); timeSeries.MetricKind = view.Aggregation.ToMetricKind(); timeSeries.Metric = GetMetric(view, labels, metricDescriptor, domain); Point point = ExtractPointInInterval(viewData.Start, viewData.End, view.Aggregation, points); var timeSeriesPoints = new List <Point> { point }; timeSeries.Points.AddRange(timeSeriesPoints); timeSeriesList.Add(timeSeries); } return(timeSeriesList); }
private static String CreateErrorMessageForAggregation(IAggregation aggregation, IAggregationData aggregationData) { return("Aggregation and AggregationData types mismatch. " + "Aggregation: " + aggregation + " AggregationData: " + aggregationData); }
private static void CheckAggregation(IAggregation aggregation, IAggregationData aggregationData, IMeasure measure) { aggregation.Match <object>( (arg) => { measure.Match <object>( (arg1) => { if (!(aggregationData is ISumDataDouble)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg1) => { if (!(aggregationData is ISumDataLong)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg1) => { throw new ArgumentException(); }); return(null); }, (arg) => { if (!(aggregationData is ICountData)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg) => { if (!(aggregationData is IMeanData)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg) => { if (!(aggregationData is IDistributionData)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg) => { measure.Match <object>( (arg1) => { if (!(aggregationData is ILastValueDataDouble)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg1) => { if (!(aggregationData is ILastValueDataLong)) { throw new ArgumentException(CreateErrorMessageForAggregation(aggregation, aggregationData)); } return(null); }, (arg1) => { throw new ArgumentException(); }); return(null); }, (arg) => { throw new ArgumentException(); } ); }
protected internal List <Metric> CreateMetrics(TagValues tagValues, IAggregationData agg, IViewData viewData, long timeStamp) { List <Metric> results = new List <Metric>(); var unit = viewData.View.Measure.Unit; var name = viewData.View.Name.AsString; var tags = GetTagKeysAndValues(viewData.View.Columns, tagValues.Values); var statistic = GetStatistic(viewData.View.Aggregation, viewData.View.Measure); agg.Match <object>( (arg) => { if (statistic == "unknown") { statistic = "total"; } tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.Sum)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "total"; } tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.Sum)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "count"; } tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.Count)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "total"; } IDictionary <string, string> copy = new Dictionary <string, string>(tags); copy["statistic"] = "count"; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, "count", copy, arg.Count)); copy = new Dictionary <string, string>(tags); copy["statistic"] = "mean"; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, copy, arg.Mean)); tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.Count * arg.Mean)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "total"; } IDictionary <string, string> copy = new Dictionary <string, string>(tags); copy["statistic"] = "count"; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, "count", copy, arg.Count)); copy = new Dictionary <string, string>(tags); copy["statistic"] = "mean"; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, copy, arg.Mean)); copy = new Dictionary <string, string>(tags); copy["statistic"] = "max"; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, copy, arg.Max)); tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.Count * arg.Mean)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "value"; } tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.LastValue)); return(null); }, (arg) => { if (statistic == "unknown") { statistic = "value"; } tags["statistic"] = statistic; results.Add(new Metric(name, MetricType.GAUGE, timeStamp, unit, tags, arg.LastValue)); return(null); }, (arg) => { return(null); }); return(results); }
public abstract IList <Metric> CreateMetrics(IViewData viewData, IAggregationData aggregation, TagValues tagValues, long timeStamp);
public void GetMetricSamples_ReturnsExpected() { var opts = new MetricsEndpointOptions(); var stats = new OpenCensusStats(); var ep = new MetricsEndpoint(opts, stats); SetupTestView(stats, Sum.Create(), null, "test.test1"); var viewData = stats.ViewManager.GetView(ViewName.Create("test.test1")); IAggregationData aggData = SumDataDouble.Create(100); Assert.NotNull(viewData); var result = ep.GetMetricSamples(aggData, viewData); Assert.NotNull(result); Assert.Single(result); var sample = result[0]; Assert.Equal(100, sample.Value); Assert.Equal(MetricStatistic.TOTALTIME, sample.Statistic); SetupTestView(stats, Sum.Create(), null, "test.test2"); viewData = stats.ViewManager.GetView(ViewName.Create("test.test2")); aggData = SumDataLong.Create(100); Assert.NotNull(viewData); result = ep.GetMetricSamples(aggData, viewData); Assert.NotNull(result); Assert.Single(result); sample = result[0]; Assert.Equal(100, sample.Value); Assert.Equal(MetricStatistic.TOTALTIME, sample.Statistic); SetupTestView(stats, Count.Create(), null, "test.test3"); viewData = stats.ViewManager.GetView(ViewName.Create("test.test3")); aggData = CountData.Create(100); Assert.NotNull(viewData); result = ep.GetMetricSamples(aggData, viewData); Assert.NotNull(result); Assert.Single(result); sample = result[0]; Assert.Equal(100, sample.Value); Assert.Equal(MetricStatistic.COUNT, sample.Statistic); SetupTestView(stats, Mean.Create(), null, "test.test4"); viewData = stats.ViewManager.GetView(ViewName.Create("test.test4")); aggData = MeanData.Create(100, 50, 1, 500); Assert.NotNull(viewData); result = ep.GetMetricSamples(aggData, viewData); Assert.NotNull(result); Assert.Equal(2, result.Count); sample = result[0]; Assert.Equal(50, sample.Value); Assert.Equal(MetricStatistic.COUNT, sample.Statistic); sample = result[1]; Assert.Equal(100 * 50, sample.Value); Assert.Equal(MetricStatistic.TOTALTIME, sample.Statistic); SetupTestView(stats, Distribution.Create(BucketBoundaries.Create(new List <double>() { 0.0, 10.0, 20.0 })), null, "test.test5"); viewData = stats.ViewManager.GetView(ViewName.Create("test.test5")); aggData = DistributionData.Create(100, 50, 5, 200, 5, new List <long>() { 10, 20, 20 }); Assert.NotNull(viewData); result = ep.GetMetricSamples(aggData, viewData); Assert.NotNull(result); Assert.Equal(3, result.Count); sample = result[0]; Assert.Equal(50, sample.Value); Assert.Equal(MetricStatistic.COUNT, sample.Statistic); sample = result[1]; Assert.Equal(200, sample.Value); Assert.Equal(MetricStatistic.MAX, sample.Statistic); sample = result[2]; Assert.Equal(100 * 50, sample.Value); Assert.Equal(MetricStatistic.TOTALTIME, sample.Statistic); }
private static void Sum(MutableAggregation combined, IAggregationData data) { data.Match <object>( (arg) => { if (combined is MutableSum sum) { sum.Add(arg.Sum); } return(null); }, (arg) => { if (combined is MutableSum sum) { sum.Add(arg.Sum); } return(null); }, (arg) => { if (combined is MutableCount count) { count.Add(arg.Count); } return(null); }, (arg) => { if (combined is MutableMean mean) { mean.Count = mean.Count + arg.Count; mean.Sum = mean.Sum + (arg.Count * arg.Mean); if (arg.Min < mean.Min) { mean.Min = arg.Min; } if (arg.Max > mean.Max) { mean.Max = arg.Max; } } return(null); }, (arg) => { if (combined is MutableDistribution dist) { // Algorithm for calculating the combination of sum of squared deviations: // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm. if (dist.Count + arg.Count > 0) { var delta = arg.Mean - dist.Mean; dist.SumOfSquaredDeviations = dist.SumOfSquaredDeviations + arg.SumOfSquaredDeviations + (Math.Pow(delta, 2) * dist.Count * arg.Count / (dist.Count + arg.Count)); } dist.Count += arg.Count; dist.Sum += arg.Mean * arg.Count; dist.Mean = dist.Sum / dist.Count; if (arg.Min < dist.Min) { dist.Min = arg.Min; } if (arg.Max > dist.Max) { dist.Max = arg.Max; } var bucketCounts = arg.BucketCounts; for (var i = 0; i < bucketCounts.Count; i++) { dist.BucketCounts[i] += bucketCounts[i]; } } return(null); }, (arg) => { if (combined is MutableLastValue lastValue) { lastValue.Initialized = true; if (double.IsNaN(lastValue.LastValue)) { lastValue.LastValue = arg.LastValue; } else { lastValue.LastValue += arg.LastValue; } } return(null); }, (arg) => { if (combined is MutableLastValue lastValue) { lastValue.Initialized = true; if (double.IsNaN(lastValue.LastValue)) { lastValue.LastValue = arg.LastValue; } else { lastValue.LastValue += arg.LastValue; } } return(null); }, (arg) => { throw new ArgumentException(); }); }
protected internal List <MetricSample> GetMetricSamples(IAggregationData agg, IViewData viewData) { List <MetricSample> results = new List <MetricSample>(); MetricStatistic statistic = GetStatistic(viewData.View.Aggregation, viewData.View.Measure); agg.Match <object>( (arg) => { if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.TOTAL; } results.Add(new MetricSample(statistic, arg.Sum)); return(null); }, (arg) => { if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.TOTAL; } results.Add(new MetricSample(statistic, arg.Sum)); return(null); }, (arg) => { if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.COUNT; } results.Add(new MetricSample(statistic, arg.Count)); return(null); }, (arg) => { results.Add(new MetricSample(MetricStatistic.COUNT, arg.Count)); if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.TOTAL; } results.Add(new MetricSample(statistic, arg.Mean * arg.Count)); return(null); }, (arg) => { results.Add(new MetricSample(MetricStatistic.COUNT, arg.Count)); results.Add(new MetricSample(MetricStatistic.MAX, arg.Max)); if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.TOTAL; } results.Add(new MetricSample(statistic, arg.Mean * arg.Count)); return(null); }, (arg) => { if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.VALUE; } results.Add(new MetricSample(statistic, arg.LastValue)); return(null); }, (arg) => { if (statistic == MetricStatistic.UNKNOWN) { statistic = MetricStatistic.VALUE; } results.Add(new MetricSample(statistic, arg.LastValue)); return(null); }, (arg) => { return(null); }); return(results); }