Skip to content

Commit

Permalink
Fix minmax and basicstats aggregators to use all number types
Browse files Browse the repository at this point in the history
These aggregators were not working with other numbers type not being
float64 or int64.
Telegraf uses externals libs that could use other types.
  • Loading branch information
adrianlzt committed Jun 15, 2018
1 parent 7781507 commit f6ffc54
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 14 deletions.
17 changes: 10 additions & 7 deletions plugins/aggregators/basicstats/basicstats.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package basicstats
import (
"log"
"math"
"reflect"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/aggregators"
Expand Down Expand Up @@ -240,15 +241,17 @@ func (m *BasicStats) Reset() {
m.cache = make(map[uint64]aggregate)
}

func convert(in interface{}) (float64, bool) {
switch v := in.(type) {
case float64:
return v, true
case int64:
return float64(v), true
default:
// https://stackoverflow.com/a/25124842
var floatType = reflect.TypeOf(float64(0))

func convert(unk interface{}) (float64, bool) {
v := reflect.ValueOf(unk)
v = reflect.Indirect(v)
if !v.Type().ConvertibleTo(floatType) {
return 0, false
}
fv := v.Convert(floatType)
return fv.Float(), true
}

func init() {
Expand Down
147 changes: 147 additions & 0 deletions plugins/aggregators/basicstats/basicstats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ var m2, _ = metric.New("m1",
"c": float64(4),
"d": float64(6),
"e": float64(200),
"f": uint64(200),
"g": uint32(200),
"h": uint16(200),
"i": uint(200),
"j": int32(200),
"k": int16(200),
"l": int(200),
"ignoreme": "string",
"andme": true,
},
Expand Down Expand Up @@ -81,6 +88,34 @@ func TestBasicStatsWithPeriod(t *testing.T) {
"e_max": float64(200),
"e_min": float64(200),
"e_mean": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"g_count": float64(1), //g
"g_max": float64(200),
"g_min": float64(200),
"g_mean": float64(200),
"h_count": float64(1), //h
"h_max": float64(200),
"h_min": float64(200),
"h_mean": float64(200),
"i_count": float64(1), //i
"i_max": float64(200),
"i_min": float64(200),
"i_mean": float64(200),
"j_count": float64(1), //j
"j_max": float64(200),
"j_min": float64(200),
"j_mean": float64(200),
"k_count": float64(1), //k
"k_max": float64(200),
"k_min": float64(200),
"k_mean": float64(200),
"l_count": float64(1), //l
"l_max": float64(200),
"l_min": float64(200),
"l_mean": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -144,6 +179,34 @@ func TestBasicStatsDifferentPeriods(t *testing.T) {
"e_max": float64(200),
"e_min": float64(200),
"e_mean": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"g_count": float64(1), //g
"g_max": float64(200),
"g_min": float64(200),
"g_mean": float64(200),
"h_count": float64(1), //h
"h_max": float64(200),
"h_min": float64(200),
"h_mean": float64(200),
"i_count": float64(1), //i
"i_max": float64(200),
"i_min": float64(200),
"i_mean": float64(200),
"j_count": float64(1), //j
"j_max": float64(200),
"j_min": float64(200),
"j_mean": float64(200),
"k_count": float64(1), //k
"k_max": float64(200),
"k_min": float64(200),
"k_mean": float64(200),
"l_count": float64(1), //l
"l_max": float64(200),
"l_min": float64(200),
"l_mean": float64(200),
}
expectedTags = map[string]string{
"foo": "bar",
Expand All @@ -169,6 +232,13 @@ func TestBasicStatsWithOnlyCount(t *testing.T) {
"c_count": float64(2),
"d_count": float64(2),
"e_count": float64(1),
"f_count": float64(1),
"g_count": float64(1),
"h_count": float64(1),
"i_count": float64(1),
"j_count": float64(1),
"k_count": float64(1),
"l_count": float64(1),
}
expectedTags := map[string]string{
"foo": "bar",
Expand All @@ -194,6 +264,13 @@ func TestBasicStatsWithOnlyMin(t *testing.T) {
"c_min": float64(2),
"d_min": float64(2),
"e_min": float64(200),
"f_min": float64(200),
"g_min": float64(200),
"h_min": float64(200),
"i_min": float64(200),
"j_min": float64(200),
"k_min": float64(200),
"l_min": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand All @@ -219,6 +296,13 @@ func TestBasicStatsWithOnlyMax(t *testing.T) {
"c_max": float64(4),
"d_max": float64(6),
"e_max": float64(200),
"f_max": float64(200),
"g_max": float64(200),
"h_max": float64(200),
"i_max": float64(200),
"j_max": float64(200),
"k_max": float64(200),
"l_max": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand All @@ -244,6 +328,13 @@ func TestBasicStatsWithOnlyMean(t *testing.T) {
"c_mean": float64(3),
"d_mean": float64(4),
"e_mean": float64(200),
"f_mean": float64(200),
"g_mean": float64(200),
"h_mean": float64(200),
"i_mean": float64(200),
"j_mean": float64(200),
"k_mean": float64(200),
"l_mean": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand All @@ -269,6 +360,13 @@ func TestBasicStatsWithOnlySum(t *testing.T) {
"c_sum": float64(6),
"d_sum": float64(8),
"e_sum": float64(200),
"f_sum": float64(200),
"g_sum": float64(200),
"h_sum": float64(200),
"i_sum": float64(200),
"j_sum": float64(200),
"k_sum": float64(200),
"l_sum": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -399,6 +497,20 @@ func TestBasicStatsWithMinAndMax(t *testing.T) {
"d_min": float64(2),
"e_max": float64(200), //e
"e_min": float64(200),
"f_max": float64(200), //f
"f_min": float64(200),
"g_max": float64(200), //g
"g_min": float64(200),
"h_max": float64(200), //h
"h_min": float64(200),
"i_max": float64(200), //i
"i_min": float64(200),
"j_max": float64(200), //j
"j_min": float64(200),
"k_max": float64(200), //k
"k_min": float64(200),
"l_max": float64(200), //l
"l_min": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -450,6 +562,41 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"e_min": float64(200),
"e_mean": float64(200),
"e_sum": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"f_sum": float64(200),
"g_count": float64(1), //g
"g_max": float64(200),
"g_min": float64(200),
"g_mean": float64(200),
"g_sum": float64(200),
"h_count": float64(1), //h
"h_max": float64(200),
"h_min": float64(200),
"h_mean": float64(200),
"h_sum": float64(200),
"i_count": float64(1), //i
"i_max": float64(200),
"i_min": float64(200),
"i_mean": float64(200),
"i_sum": float64(200),
"j_count": float64(1), //j
"j_max": float64(200),
"j_min": float64(200),
"j_mean": float64(200),
"j_sum": float64(200),
"k_count": float64(1), //k
"k_max": float64(200),
"k_min": float64(200),
"k_mean": float64(200),
"k_sum": float64(200),
"l_count": float64(1), //l
"l_max": float64(200),
"l_min": float64(200),
"l_mean": float64(200),
"l_sum": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down
18 changes: 11 additions & 7 deletions plugins/aggregators/minmax/minmax.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package minmax

import (
"reflect"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/aggregators"
)
Expand Down Expand Up @@ -101,15 +103,17 @@ func (m *MinMax) Reset() {
m.cache = make(map[uint64]aggregate)
}

func convert(in interface{}) (float64, bool) {
switch v := in.(type) {
case float64:
return v, true
case int64:
return float64(v), true
default:
// https://stackoverflow.com/a/25124842
var floatType = reflect.TypeOf(float64(0))

func convert(unk interface{}) (float64, bool) {
v := reflect.ValueOf(unk)
v = reflect.Indirect(v)
if !v.Type().ConvertibleTo(floatType) {
return 0, false
}
fv := v.Convert(floatType)
return fv.Float(), true
}

func init() {
Expand Down
35 changes: 35 additions & 0 deletions plugins/aggregators/minmax/minmax_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ var m2, _ = metric.New("m1",
"i": float64(1),
"j": float64(1),
"k": float64(200),
"l": uint64(200),
"m": uint32(200),
"n": uint16(200),
"o": uint(200),
"p": int32(200),
"q": int16(200),
"r": int(200),
"ignoreme": "string",
"andme": true,
},
Expand Down Expand Up @@ -85,6 +92,20 @@ func TestMinMaxWithPeriod(t *testing.T) {
"j_min": float64(1),
"k_max": float64(200),
"k_min": float64(200),
"l_max": float64(200),
"l_min": float64(200),
"m_max": float64(200),
"m_min": float64(200),
"n_max": float64(200),
"n_min": float64(200),
"o_max": float64(200),
"o_min": float64(200),
"p_max": float64(200),
"p_min": float64(200),
"q_max": float64(200),
"q_min": float64(200),
"r_max": float64(200),
"r_min": float64(200),
}
expectedTags := map[string]string{
"foo": "bar",
Expand Down Expand Up @@ -154,6 +175,20 @@ func TestMinMaxDifferentPeriods(t *testing.T) {
"j_min": float64(1),
"k_max": float64(200),
"k_min": float64(200),
"l_max": float64(200),
"l_min": float64(200),
"m_max": float64(200),
"m_min": float64(200),
"n_max": float64(200),
"n_min": float64(200),
"o_max": float64(200),
"o_min": float64(200),
"p_max": float64(200),
"p_min": float64(200),
"q_max": float64(200),
"q_min": float64(200),
"r_max": float64(200),
"r_min": float64(200),
}
expectedTags = map[string]string{
"foo": "bar",
Expand Down

0 comments on commit f6ffc54

Please sign in to comment.