Skip to content

Commit

Permalink
feat(aggregators.basicstats): Add first field (#15948)
Browse files Browse the repository at this point in the history
  • Loading branch information
tguenneguez authored Oct 7, 2024
1 parent 19c31b5 commit 31ddd69
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 7 deletions.
9 changes: 5 additions & 4 deletions plugins/aggregators/basicstats/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# BasicStats Aggregator Plugin

The BasicStats aggregator plugin gives count, diff, max, min, mean,
non_negative_diff, sum, s2(variance), stdev for a set of values, emitting the
aggregate every `period` seconds.
non_negative_diff, sum, s2(variance), stdev for a set of values, last and
first, emitting the aggregate every `period` seconds.

## Global configuration options <!-- @/docs/includes/plugin_config.md -->

Expand All @@ -26,7 +26,7 @@ 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","percent_change","stdev","s2","sum","interval","last"]
# stats = ["count","min","max","mean","variance","stdev"]
```

- stats
Expand All @@ -52,6 +52,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
- field1_stdev (standard deviation)
- field1_interval (interval in nanoseconds)
- field1_last (last aggregated value)
- field1_first (first aggregated value)

## Tags

Expand All @@ -65,5 +66,5 @@ system,host=tars load1=1 1475583990000000000
system,host=tars load1_count=2,load1_diff=0,load1_rate=0,load1_max=1,load1_min=1,load1_mean=1,load1_sum=2,load1_s2=0,load1_stdev=0,load1_interval=10000000000i,load1_last=1 1475584010000000000
system,host=tars load1=1 1475584020000000000
system,host=tars load1=3 1475584030000000000
system,host=tars load1_count=2,load1_diff=2,load1_rate=0.2,load1_max=3,load1_min=1,load1_mean=2,load1_sum=4,load1_s2=2,load1_stdev=1.414162,load1_interval=10000000000i,load1_last=3 1475584010000000000
system,host=tars load1_count=2,load1_diff=2,load1_rate=0.2,load1_max=3,load1_min=1,load1_mean=2,load1_sum=4,load1_s2=2,load1_stdev=1.414162,load1_interval=10000000000i,load1_last=3,load1_first=3 1475584010000000000
```
10 changes: 10 additions & 0 deletions plugins/aggregators/basicstats/basicstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type configuredStats struct {
percentChange bool
interval bool
last bool
first bool
}

func NewBasicStats() *BasicStats {
Expand All @@ -60,6 +61,7 @@ type basicstats struct {
rate float64
interval time.Duration
last float64
first float64
M2 float64 // intermediate value for variance/stdev
PREVIOUS float64 // intermediate value for diff
TIME time.Time // intermediate value for rate
Expand Down Expand Up @@ -89,6 +91,7 @@ func (b *BasicStats) Add(in telegraf.Metric) {
diff: 0.0,
rate: 0.0,
last: fv,
first: fv,
M2: 0.0,
PREVIOUS: fv,
TIME: in.Time(),
Expand All @@ -111,6 +114,7 @@ func (b *BasicStats) Add(in telegraf.Metric) {
rate: 0.0,
interval: 0,
last: fv,
first: fv,
M2: 0.0,
PREVIOUS: fv,
TIME: in.Time(),
Expand Down Expand Up @@ -181,6 +185,9 @@ func (b *BasicStats) Push(acc telegraf.Accumulator) {
if b.statsConfig.last {
fields[k+"_last"] = v.last
}
if b.statsConfig.first {
fields[k+"_first"] = v.first
}

// v.count always >=1
if v.count > 1 {
Expand Down Expand Up @@ -254,6 +261,8 @@ func (b *BasicStats) parseStats() *configuredStats {
parsed.interval = true
case "last":
parsed.last = true
case "first":
parsed.first = true
default:
b.Log.Warnf("Unrecognized basic stat %q, ignoring", name)
}
Expand All @@ -279,6 +288,7 @@ func (b *BasicStats) initConfiguredStats() {
percentChange: false,
interval: false,
last: false,
first: false,
}
} else {
b.statsConfig = b.parseStats()
Expand Down
50 changes: 48 additions & 2 deletions plugins/aggregators/basicstats/basicstats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestBasicStatsWithPeriod(t *testing.T) {
func TestBasicStatsDifferentPeriods(t *testing.T) {
acc := testutil.Accumulator{}
minmax := NewBasicStats()
minmax.Stats = []string{"count", "max", "min", "mean", "last"}
minmax.Stats = []string{"count", "max", "min", "mean", "last", "first"}
minmax.Log = testutil.Logger{}
minmax.initConfiguredStats()

Expand All @@ -123,26 +123,31 @@ func TestBasicStatsDifferentPeriods(t *testing.T) {
"a_min": float64(1),
"a_mean": float64(1),
"a_last": float64(1),
"a_first": float64(1),
"b_count": float64(1), // b
"b_max": float64(1),
"b_min": float64(1),
"b_mean": float64(1),
"b_last": float64(1),
"b_first": float64(1),
"c_count": float64(1), // c
"c_max": float64(2),
"c_min": float64(2),
"c_mean": float64(2),
"c_last": float64(2),
"c_first": float64(2),
"d_count": float64(1), // d
"d_max": float64(2),
"d_min": float64(2),
"d_mean": float64(2),
"d_last": float64(2),
"d_first": float64(2),
"g_count": float64(1), // g
"g_max": float64(3),
"g_min": float64(3),
"g_mean": float64(3),
"g_last": float64(3),
"g_first": float64(3),
}
expectedTags := map[string]string{
"foo": "bar",
Expand All @@ -159,36 +164,43 @@ func TestBasicStatsDifferentPeriods(t *testing.T) {
"a_min": float64(1),
"a_mean": float64(1),
"a_last": float64(1),
"a_first": float64(1),
"b_count": float64(1), // b
"b_max": float64(3),
"b_min": float64(3),
"b_mean": float64(3),
"b_last": float64(3),
"b_first": float64(3),
"c_count": float64(1), // c
"c_max": float64(4),
"c_min": float64(4),
"c_mean": float64(4),
"c_last": float64(4),
"c_first": float64(4),
"d_count": float64(1), // d
"d_max": float64(6),
"d_min": float64(6),
"d_mean": float64(6),
"d_last": float64(6),
"d_first": float64(6),
"e_count": float64(1), // e
"e_max": float64(200),
"e_min": float64(200),
"e_mean": float64(200),
"e_last": float64(200),
"e_first": float64(200),
"f_count": float64(1), // f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"f_last": float64(200),
"f_first": float64(200),
"g_count": float64(1), // g
"g_max": float64(1),
"g_min": float64(1),
"g_mean": float64(1),
"g_last": float64(1),
"g_first": float64(1),
}
expectedTags = map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -629,7 +641,7 @@ func TestBasicStatsWithAllStats(t *testing.T) {
acc := testutil.Accumulator{}
minmax := NewBasicStats()
minmax.Log = testutil.Logger{}
minmax.Stats = []string{"count", "min", "max", "mean", "stdev", "s2", "sum", "last"}
minmax.Stats = []string{"count", "min", "max", "mean", "stdev", "s2", "sum", "last", "first"}
minmax.initConfiguredStats()

minmax.Add(m1)
Expand All @@ -645,6 +657,7 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"a_s2": float64(0),
"a_sum": float64(2),
"a_last": float64(1),
"a_first": float64(1),
"b_count": float64(2), // b
"b_max": float64(3),
"b_min": float64(1),
Expand All @@ -653,6 +666,7 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"b_sum": float64(4),
"b_last": float64(3),
"b_stdev": math.Sqrt(2),
"b_first": float64(1),
"c_count": float64(2), // c
"c_max": float64(4),
"c_min": float64(2),
Expand All @@ -661,6 +675,7 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"c_stdev": math.Sqrt(2),
"c_sum": float64(6),
"c_last": float64(4),
"c_first": float64(2),
"d_count": float64(2), // d
"d_max": float64(6),
"d_min": float64(2),
Expand All @@ -669,18 +684,21 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"d_stdev": math.Sqrt(8),
"d_sum": float64(8),
"d_last": float64(6),
"d_first": float64(2),
"e_count": float64(1), // e
"e_max": float64(200),
"e_min": float64(200),
"e_mean": float64(200),
"e_sum": float64(200),
"e_last": float64(200),
"e_first": float64(200),
"f_count": float64(1), // f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"f_sum": float64(200),
"f_last": float64(200),
"f_first": float64(200),
"g_count": float64(2), // g
"g_max": float64(3),
"g_min": float64(1),
Expand All @@ -689,6 +707,7 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"g_stdev": math.Sqrt(2),
"g_sum": float64(4),
"g_last": float64(1),
"g_first": float64(3),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -778,3 +797,30 @@ func TestBasicStatsWithOnlyLast(t *testing.T) {
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
}

func TestBasicStatsWithOnlyFirst(t *testing.T) {
aggregator := NewBasicStats()
aggregator.Stats = []string{"first"}
aggregator.Log = testutil.Logger{}
aggregator.initConfiguredStats()

aggregator.Add(m1)
aggregator.Add(m2)

acc := testutil.Accumulator{}
aggregator.Push(&acc)

expectedFields := map[string]interface{}{
"a_first": float64(1),
"b_first": float64(1),
"c_first": float64(2),
"d_first": float64(2),
"e_first": float64(200),
"f_first": float64(200),
"g_first": float64(3),
}
expectedTags := map[string]string{
"foo": "bar",
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
}
2 changes: 1 addition & 1 deletion plugins/aggregators/basicstats/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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","percent_change","stdev","s2","sum","interval","last"]
# stats = ["count","min","max","mean","variance","stdev"]

0 comments on commit 31ddd69

Please sign in to comment.