Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aggregators.basicstats): Add first field #15948

Merged
merged 7 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"]
Loading