Allow graphite parser to create Inf and NaN values (#6420)

This commit is contained in:
Daniel Nelson 2019-09-19 20:03:10 -07:00 committed by GitHub
parent e553341879
commit 8d96dd71c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 30 deletions

View File

@ -1,14 +0,0 @@
package graphite
import "fmt"
// An UnsupposedValueError is returned when a parsed value is not
// supposed.
type UnsupposedValueError struct {
Field string
Value float64
}
func (err *UnsupposedValueError) Error() string {
return fmt.Sprintf(`field "%s" value: "%v" is unsupported`, err.Field, err.Value)
}

View File

@ -9,9 +9,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/influxdata/telegraf/internal/templating"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/templating"
"github.com/influxdata/telegraf/metric" "github.com/influxdata/telegraf/metric"
) )
@ -121,10 +120,6 @@ func (p *GraphiteParser) ParseLine(line string) (telegraf.Metric, error) {
return nil, fmt.Errorf(`field "%s" value: %s`, fields[0], err) return nil, fmt.Errorf(`field "%s" value: %s`, fields[0], err)
} }
if math.IsNaN(v) || math.IsInf(v, 0) {
return nil, &UnsupposedValueError{Field: fields[0], Value: v}
}
fieldValues := map[string]interface{}{} fieldValues := map[string]interface{}{}
if field != "" { if field != "" {
fieldValues[field] = v fieldValues[field] = v

View File

@ -1,14 +1,14 @@
package graphite package graphite
import ( import (
"reflect" "math"
"strconv" "strconv"
"testing" "testing"
"time" "time"
"github.com/influxdata/telegraf/internal/templating" "github.com/influxdata/telegraf/internal/templating"
"github.com/influxdata/telegraf/metric" "github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -355,14 +355,40 @@ func TestParse(t *testing.T) {
func TestParseNaN(t *testing.T) { func TestParseNaN(t *testing.T) {
p, err := NewGraphiteParser("", []string{"measurement*"}, nil) p, err := NewGraphiteParser("", []string{"measurement*"}, nil)
assert.NoError(t, err) require.NoError(t, err)
_, err = p.ParseLine("servers.localhost.cpu_load NaN 1435077219") m, err := p.ParseLine("servers.localhost.cpu_load NaN 1435077219")
assert.Error(t, err) require.NoError(t, err)
if _, ok := err.(*UnsupposedValueError); !ok { expected := testutil.MustMetric(
t.Fatalf("expected *ErrUnsupportedValue, got %v", reflect.TypeOf(err)) "servers.localhost.cpu_load",
} map[string]string{},
map[string]interface{}{
"value": math.NaN(),
},
time.Unix(1435077219, 0),
)
testutil.RequireMetricEqual(t, expected, m)
}
func TestParseInf(t *testing.T) {
p, err := NewGraphiteParser("", []string{"measurement*"}, nil)
require.NoError(t, err)
m, err := p.ParseLine("servers.localhost.cpu_load +Inf 1435077219")
require.NoError(t, err)
expected := testutil.MustMetric(
"servers.localhost.cpu_load",
map[string]string{},
map[string]interface{}{
"value": math.Inf(1),
},
time.Unix(1435077219, 0),
)
testutil.RequireMetricEqual(t, expected, m)
} }
func TestFilterMatchDefault(t *testing.T) { func TestFilterMatchDefault(t *testing.T) {

View File

@ -129,7 +129,7 @@ func IgnoreTime() cmp.Option {
} }
// MetricEqual returns true if the metrics are equal. // MetricEqual returns true if the metrics are equal.
func MetricEqual(expected, actual telegraf.Metric) bool { func MetricEqual(expected, actual telegraf.Metric, opts ...cmp.Option) bool {
var lhs, rhs *metricDiff var lhs, rhs *metricDiff
if expected != nil { if expected != nil {
lhs = newMetricDiff(expected) lhs = newMetricDiff(expected)
@ -138,7 +138,8 @@ func MetricEqual(expected, actual telegraf.Metric) bool {
rhs = newMetricDiff(actual) rhs = newMetricDiff(actual)
} }
return cmp.Equal(lhs, rhs) opts = append(opts, cmpopts.EquateNaNs())
return cmp.Equal(lhs, rhs, opts...)
} }
// RequireMetricEqual halts the test with an error if the metrics are not // RequireMetricEqual halts the test with an error if the metrics are not
@ -154,6 +155,7 @@ func RequireMetricEqual(t *testing.T, expected, actual telegraf.Metric, opts ...
rhs = newMetricDiff(actual) rhs = newMetricDiff(actual)
} }
opts = append(opts, cmpopts.EquateNaNs())
if diff := cmp.Diff(lhs, rhs, opts...); diff != "" { if diff := cmp.Diff(lhs, rhs, opts...); diff != "" {
t.Fatalf("telegraf.Metric\n--- expected\n+++ actual\n%s", diff) t.Fatalf("telegraf.Metric\n--- expected\n+++ actual\n%s", diff)
} }
@ -172,6 +174,8 @@ func RequireMetricsEqual(t *testing.T, expected, actual []telegraf.Metric, opts
for _, m := range actual { for _, m := range actual {
rhs = append(rhs, newMetricDiff(m)) rhs = append(rhs, newMetricDiff(m))
} }
opts = append(opts, cmpopts.EquateNaNs())
if diff := cmp.Diff(lhs, rhs, opts...); diff != "" { if diff := cmp.Diff(lhs, rhs, opts...); diff != "" {
t.Fatalf("[]telegraf.Metric\n--- expected\n+++ actual\n%s", diff) t.Fatalf("[]telegraf.Metric\n--- expected\n+++ actual\n%s", diff)
} }