From ca1325998924cc32d89b525fd78a29d27e5e26fc Mon Sep 17 00:00:00 2001 From: Joshua Powers Date: Tue, 2 May 2023 05:24:43 -0600 Subject: [PATCH] feat(aggregators.basicstats): Add percentage change (#13118) --- plugins/aggregators/basicstats/README.md | 8 ++++-- plugins/aggregators/basicstats/basicstats.go | 7 ++++++ .../aggregators/basicstats/basicstats_test.go | 25 +++++++++++++++++++ plugins/aggregators/basicstats/sample.conf | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/plugins/aggregators/basicstats/README.md b/plugins/aggregators/basicstats/README.md index e891cef9e..04f46b170 100644 --- a/plugins/aggregators/basicstats/README.md +++ b/plugins/aggregators/basicstats/README.md @@ -26,11 +26,14 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. drop_original = false ## Configures which basic stats to push as fields - # stats = ["count","diff","rate","min","max","mean","non_negative_diff","non_negative_rate","stdev","s2","sum","interval"] + # stats = ["count","diff","rate","min","max","mean","non_negative_diff","non_negative_rate","percent_change","stdev","s2","sum","interval"] ``` - stats - - If not specified, then `count`, `min`, `max`, `mean`, `stdev`, and `s2` are aggregated and pushed as fields. `sum`, `diff` and `non_negative_diff` are not aggregated by default to maintain backwards compatibility. + - If not specified, then `count`, `min`, `max`, `mean`, `stdev`, and `s2` are + aggregated and pushed as fields. `sum`, `diff`, `non_negative_diff`, + `percent_change` are not aggregated by default to maintain backwards + compatibility. - If empty array, no stats are aggregated ## Measurements & Fields @@ -44,6 +47,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. - field1_mean - field1_non_negative_diff (non-negative difference) - field1_non_negative_rate (non-negative rate per second) + - field1_percent_change - field1_sum - field1_s2 (variance) - field1_stdev (standard deviation) diff --git a/plugins/aggregators/basicstats/basicstats.go b/plugins/aggregators/basicstats/basicstats.go index 333129652..0341d054b 100644 --- a/plugins/aggregators/basicstats/basicstats.go +++ b/plugins/aggregators/basicstats/basicstats.go @@ -33,6 +33,7 @@ type configuredStats struct { nonNegativeDiff bool rate bool nonNegativeRate bool + percentChange bool interval bool } @@ -191,6 +192,9 @@ func (b *BasicStats) Push(acc telegraf.Accumulator) { if b.statsConfig.rate { fields[k+"_rate"] = v.rate } + if b.statsConfig.percentChange { + fields[k+"_percent_change"] = v.diff / v.LAST * 100 + } if b.statsConfig.nonNegativeRate && v.diff >= 0 { fields[k+"_non_negative_rate"] = v.rate } @@ -235,6 +239,8 @@ func (b *BasicStats) parseStats() *configuredStats { parsed.rate = true case "non_negative_rate": parsed.nonNegativeRate = true + case "percent_change": + parsed.percentChange = true case "interval": parsed.interval = true default: @@ -258,6 +264,7 @@ func (b *BasicStats) getConfiguredStats() { nonNegativeDiff: false, rate: false, nonNegativeRate: false, + percentChange: false, } } else { b.statsConfig = b.parseStats() diff --git a/plugins/aggregators/basicstats/basicstats_test.go b/plugins/aggregators/basicstats/basicstats_test.go index 3f0862497..71159879d 100644 --- a/plugins/aggregators/basicstats/basicstats_test.go +++ b/plugins/aggregators/basicstats/basicstats_test.go @@ -536,6 +536,31 @@ func TestBasicStatsWithNonNegativeRate(t *testing.T) { } acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags) } + +func TestBasicStatsWithPctChange(t *testing.T) { + aggregator := NewBasicStats() + aggregator.Stats = []string{"percent_change"} + aggregator.Log = testutil.Logger{} + aggregator.getConfiguredStats() + + aggregator.Add(m1) + aggregator.Add(m2) + + acc := testutil.Accumulator{} + aggregator.Push(&acc) + expectedFields := map[string]interface{}{ + "a_percent_change": float64(0), + "b_percent_change": float64(200), + "c_percent_change": float64(100), + "d_percent_change": float64(200), + "g_percent_change": float64(-66.66666666666666), + } + expectedTags := map[string]string{ + "foo": "bar", + } + acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags) +} + func TestBasicStatsWithInterval(t *testing.T) { aggregator := NewBasicStats() aggregator.Stats = []string{"interval"} diff --git a/plugins/aggregators/basicstats/sample.conf b/plugins/aggregators/basicstats/sample.conf index 8c18e6d2f..b4296ec0b 100644 --- a/plugins/aggregators/basicstats/sample.conf +++ b/plugins/aggregators/basicstats/sample.conf @@ -8,4 +8,4 @@ drop_original = false ## Configures which basic stats to push as fields - # stats = ["count","diff","rate","min","max","mean","non_negative_diff","non_negative_rate","stdev","s2","sum","interval"] + # stats = ["count","diff","rate","min","max","mean","non_negative_diff","non_negative_rate","percent_change","stdev","s2","sum","interval"]