From 49dda7e5c1961c59218d75efc90284c156517042 Mon Sep 17 00:00:00 2001 From: Dirk le Roux Date: Wed, 23 Nov 2016 10:02:18 +0200 Subject: [PATCH 1/3] first, delta, range passing unit tests Signed-off-by: Dirk le Roux --- public/app/core/time_series2.ts | 26 +++++++++ public/app/plugins/panel/singlestat/module.ts | 2 +- public/test/core/time_series_specs.js | 57 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/public/app/core/time_series2.ts b/public/app/core/time_series2.ts index 25a99a38ad8..4503be68710 100644 --- a/public/app/core/time_series2.ts +++ b/public/app/core/time_series2.ts @@ -102,6 +102,9 @@ export default class TimeSeries { this.stats.min = Number.MAX_VALUE; this.stats.avg = null; this.stats.current = null; + this.stats.first = null; + this.stats.delta = 0; + this.stats.range = null; this.stats.timeStep = Number.MAX_VALUE; this.allIsNull = true; this.allIsZero = true; @@ -112,6 +115,8 @@ export default class TimeSeries { var currentValue; var nonNulls = 0; var previousTime; + var previousValue = 0; + var previousDeltaUp = true; for (var i = 0; i < this.datapoints.length; i++) { currentValue = this.datapoints[i][0]; @@ -148,6 +153,24 @@ export default class TimeSeries { if (currentValue < this.stats.min) { this.stats.min = currentValue; } + if (this.stats.first === null){ + this.stats.first = currentValue; + }else{ + if (previousValue > currentValue) { // counter reset + previousDeltaUp = false; + if (i === this.datapoints.length-1) { // reset on last + this.stats.delta += currentValue; + } + }else{ + if (previousDeltaUp) { + this.stats.delta += currentValue - previousValue; // normal increment + } else { + this.stats.delta += currentValue; // account for counter reset + } + previousDeltaUp = true; + } + } + previousValue = currentValue; } if (currentValue !== 0) { @@ -167,6 +190,9 @@ export default class TimeSeries { this.stats.current = result[result.length-2][1]; } } + if (this.stats.max !== null && this.stats.min !== null) { + this.stats.range = this.stats.max - this.stats.min; + } this.stats.count = result.length; return result; diff --git a/public/app/plugins/panel/singlestat/module.ts b/public/app/plugins/panel/singlestat/module.ts index 3af89abf1d7..1da40ddd25e 100644 --- a/public/app/plugins/panel/singlestat/module.ts +++ b/public/app/plugins/panel/singlestat/module.ts @@ -21,7 +21,7 @@ class SingleStatCtrl extends MetricsPanelCtrl { invalidGaugeRange: boolean; panel: any; events: any; - valueNameOptions: any[] = ['min','max','avg', 'current', 'total', 'name']; + valueNameOptions: any[] = ['min','max','avg', 'current', 'total', 'name', 'first', 'delta', 'range']; // Set and populate defaults panelDefaults = { diff --git a/public/test/core/time_series_specs.js b/public/test/core/time_series_specs.js index 2b325cf6d46..829f74d3515 100644 --- a/public/test/core/time_series_specs.js +++ b/public/test/core/time_series_specs.js @@ -49,6 +49,63 @@ define([ expect(series.stats.avg).to.be(6.333333333333333); }); + it('the delta value should account for nulls', function() { + series = new TimeSeries({ + datapoints: [[1,2],[3,3],[null,4],[10,5],[15,6]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.delta).to.be(14); + }); + + it('the delta value should account for nulls on first', function() { + series = new TimeSeries({ + datapoints: [[null,2],[1,3],[10,4],[15,5]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.delta).to.be(14); + }); + + it('the delta value should account for nulls on last', function() { + series = new TimeSeries({ + datapoints: [[1,2],[5,3],[10,4],[null,5]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.delta).to.be(9); + }); + + it('the delta value should account for resets', function() { + series = new TimeSeries({ + datapoints: [[1,2],[5,3],[10,4],[0,5],[10,6]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.delta).to.be(19); + }); + + it('the delta value should account for resets on last', function() { + series = new TimeSeries({ + datapoints: [[1,2],[2,3],[10,4],[8,5]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.delta).to.be(17); + }); + + it('the range value should be max - min', function() { + series = new TimeSeries(testData); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.range).to.be(9); + }); + + it('first value should ingone nulls', function() { + series = new TimeSeries(testData); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.first).to.be(1); + series = new TimeSeries({ + datapoints: [[null,2],[1,3],[10,4],[8,5]] + }); + series.getFlotPairs('null', yAxisFormats); + expect(series.stats.first).to.be(1); + }); + it('with null as zero style, average value should treat nulls as 0', function() { series = new TimeSeries(testData); series.getFlotPairs('null as zero', yAxisFormats); From 6412bd2f57f16001de7570657987600199ecaebd Mon Sep 17 00:00:00 2001 From: Dirk le Roux Date: Thu, 24 Nov 2016 10:15:52 +0200 Subject: [PATCH 2/3] oAdded value type documentation to singlestat panel Signed-off-by: Dirk le Roux --- docs/sources/reference/singlestat.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/sources/reference/singlestat.md b/docs/sources/reference/singlestat.md index 3e84ee84aff..84e0336f9c4 100644 --- a/docs/sources/reference/singlestat.md +++ b/docs/sources/reference/singlestat.md @@ -23,7 +23,15 @@ The singlestat panel has a normal query editor to allow you define your exact me 1. `Big Value`: Big Value refers to how we display the main stat for the Singlestat Panel. This is always a single value that is displayed in the Panel in between two strings, `Prefix` and `Suffix`. The single number is calculated by choosing a function (min,max,average,current,total) of your metric query. This functions reduces your query into a single numeric value. 2. `Font Size`: You can use this section to select the font size of the different texts in the Singlestat Panel, i.e. prefix, value and postfix. -3. `Values`: The Value fields let you set the function (min, max, average, current, total) that your entire query is reduced into a single value with. You can also set the font size of the Value field and font-size (as a %) of the metric query that the Panel is configured with. This reduces the entire query into a single summary value that is displayed. +3. `Values`: The Value fields let you set the function (min, max, average, current, total, first, delta, range) that your entire query is reduced into a single value with. You can also set the font size of the Value field and font-size (as a %) of the metric query that the Panel is configured with. This reduces the entire query into a single summary value that is displayed. + * `min` - The smallest value in the series + * `max` - The largest value in the series + * `average` - The average of all the non-null values in the series + * `current` - The last value in the series. If the series ends on null the previous value will be used. + * `total` - The sum of all the non-null values in the series + * `first` - The first value in the series + * `delta` - The total incremental increase (of a counter) in the series. An attempt is made to account for counter resets (this will only be acurate for single instance metrics). Used to show total counter increase in time series. + * `range` - The difference between 'min' and 'max'. Useful the show the range of change for a gauge. 4. `Postfixes`: The Postfix fields let you define a custom label and font-size (as a %) to appear *after* the value 5. `Units`: Units are appended to the the Singlestat within the panel, and will respect the color and threshold settings for the value. 6. `Decimals`: The Decimal field allows you to override the automatic decimal precision, and set it explicitly. From e0073d7e543a01663a1006dd92263c2842b1a36e Mon Sep 17 00:00:00 2001 From: Dirk le Roux Date: Tue, 29 Nov 2016 08:32:51 +0200 Subject: [PATCH 3/3] Fixed spelling error --- docs/sources/reference/singlestat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/reference/singlestat.md b/docs/sources/reference/singlestat.md index 84e0336f9c4..1fb0c254c01 100644 --- a/docs/sources/reference/singlestat.md +++ b/docs/sources/reference/singlestat.md @@ -30,7 +30,7 @@ The singlestat panel has a normal query editor to allow you define your exact me * `current` - The last value in the series. If the series ends on null the previous value will be used. * `total` - The sum of all the non-null values in the series * `first` - The first value in the series - * `delta` - The total incremental increase (of a counter) in the series. An attempt is made to account for counter resets (this will only be acurate for single instance metrics). Used to show total counter increase in time series. + * `delta` - The total incremental increase (of a counter) in the series. An attempt is made to account for counter resets, but this will only be accurate for single instance metrics. Used to show total counter increase in time series. * `range` - The difference between 'min' and 'max'. Useful the show the range of change for a gauge. 4. `Postfixes`: The Postfix fields let you define a custom label and font-size (as a %) to appear *after* the value 5. `Units`: Units are appended to the the Singlestat within the panel, and will respect the color and threshold settings for the value.