diff --git a/metric.go b/metric.go index fcbb1b291..99ee30369 100644 --- a/metric.go +++ b/metric.go @@ -1,6 +1,7 @@ package telegraf import ( + "bytes" "time" "github.com/influxdata/influxdb/client/v2" @@ -68,6 +69,8 @@ func NewMetric( // a non-nil error will be returned in addition to the metrics that parsed // successfully. func ParseMetrics(buf []byte) ([]Metric, error) { + // parse even if the buffer begins with a newline + buf = bytes.TrimPrefix(buf, []byte("\n")) points, err := models.ParsePoints(buf) metrics := make([]Metric, len(points)) for i, point := range points { diff --git a/metric_test.go b/metric_test.go new file mode 100644 index 000000000..acf6dee99 --- /dev/null +++ b/metric_test.go @@ -0,0 +1,135 @@ +package telegraf + +import ( + "fmt" + "math" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +const validMs = ` +cpu,cpu=cpu0,host=foo,datacenter=us-east usage_idle=99,usage_busy=1 1454105876344540456 +` + +const invalidMs = ` +cpu, cpu=cpu0,host=foo,datacenter=us-east usage_idle=99,usage_busy=1 +cpu,host=foo usage_idle +cpu,host usage_idle=99 +cpu,host=foo usage_idle=99 very bad metric +` + +const validInvalidMs = ` +cpu,cpu=cpu0,host=foo,datacenter=us-east usage_idle=99,usage_busy=1 +cpu,cpu=cpu1,host=foo,datacenter=us-east usage_idle=51,usage_busy=49 +cpu,cpu=cpu2,host=foo,datacenter=us-east usage_idle=60,usage_busy=40 +cpu,host usage_idle=99 +` + +func TestParseValidMetrics(t *testing.T) { + metrics, err := ParseMetrics([]byte(validMs)) + assert.NoError(t, err) + assert.Len(t, metrics, 1) + m := metrics[0] + + tags := map[string]string{ + "host": "foo", + "datacenter": "us-east", + "cpu": "cpu0", + } + fields := map[string]interface{}{ + "usage_idle": float64(99), + "usage_busy": float64(1), + } + + assert.Equal(t, tags, m.Tags()) + assert.Equal(t, fields, m.Fields()) + assert.Equal(t, "cpu", m.Name()) + assert.Equal(t, int64(1454105876344540456), m.UnixNano()) +} + +func TestParseInvalidMetrics(t *testing.T) { + metrics, err := ParseMetrics([]byte(invalidMs)) + assert.Error(t, err) + assert.Len(t, metrics, 0) +} + +func TestParseValidAndInvalidMetrics(t *testing.T) { + metrics, err := ParseMetrics([]byte(validInvalidMs)) + assert.Error(t, err) + assert.Len(t, metrics, 3) +} + +func TestNewMetric(t *testing.T) { + now := time.Now() + + tags := map[string]string{ + "host": "localhost", + "datacenter": "us-east-1", + } + fields := map[string]interface{}{ + "usage_idle": float64(99), + "usage_busy": float64(1), + } + m, err := NewMetric("cpu", tags, fields, now) + assert.NoError(t, err) + + assert.Equal(t, tags, m.Tags()) + assert.Equal(t, fields, m.Fields()) + assert.Equal(t, "cpu", m.Name()) + assert.Equal(t, now, m.Time()) + assert.Equal(t, now.UnixNano(), m.UnixNano()) +} + +func TestNewMetricString(t *testing.T) { + now := time.Now() + + tags := map[string]string{ + "host": "localhost", + } + fields := map[string]interface{}{ + "usage_idle": float64(99), + } + m, err := NewMetric("cpu", tags, fields, now) + assert.NoError(t, err) + + lineProto := fmt.Sprintf("cpu,host=localhost usage_idle=99 %d", + now.UnixNano()) + assert.Equal(t, lineProto, m.String()) + + lineProtoPrecision := fmt.Sprintf("cpu,host=localhost usage_idle=99 %d", + now.Unix()) + assert.Equal(t, lineProtoPrecision, m.PrecisionString("s")) +} + +func TestNewMetricStringNoTime(t *testing.T) { + tags := map[string]string{ + "host": "localhost", + } + fields := map[string]interface{}{ + "usage_idle": float64(99), + } + m, err := NewMetric("cpu", tags, fields) + assert.NoError(t, err) + + lineProto := fmt.Sprintf("cpu,host=localhost usage_idle=99") + assert.Equal(t, lineProto, m.String()) + + lineProtoPrecision := fmt.Sprintf("cpu,host=localhost usage_idle=99") + assert.Equal(t, lineProtoPrecision, m.PrecisionString("s")) +} + +func TestNewMetricFailNaN(t *testing.T) { + now := time.Now() + + tags := map[string]string{ + "host": "localhost", + } + fields := map[string]interface{}{ + "usage_idle": math.NaN(), + } + + _, err := NewMetric("cpu", tags, fields, now) + assert.Error(t, err) +} diff --git a/plugins/outputs/prometheus_client/prometheus_client_test.go b/plugins/outputs/prometheus_client/prometheus_client_test.go index 34ef77e4c..2630e6262 100644 --- a/plugins/outputs/prometheus_client/prometheus_client_test.go +++ b/plugins/outputs/prometheus_client/prometheus_client_test.go @@ -16,9 +16,12 @@ func TestPrometheusWritePointEmptyTag(t *testing.T) { if testing.Short() { t.Skip("Skipping integration test in short mode") } + pTesting = &PrometheusClient{Listen: "localhost:9127"} + pTesting.Start() + defer pTesting.Stop() p := &prometheus.Prometheus{ - Urls: []string{"http://localhost:9126/metrics"}, + Urls: []string{"http://localhost:9127/metrics"}, } tags := make(map[string]string) pt1, _ := telegraf.NewMetric( @@ -51,33 +54,24 @@ func TestPrometheusWritePointEmptyTag(t *testing.T) { acc.AssertContainsFields(t, "prometheus_"+e.name, map[string]interface{}{"value": e.value}) } -} -func TestPrometheusWritePointTag(t *testing.T) { - if testing.Short() { - t.Skip("Skipping integration test in short mode") - } - - p := &prometheus.Prometheus{ - Urls: []string{"http://localhost:9126/metrics"}, - } - tags := make(map[string]string) + tags = make(map[string]string) tags["testtag"] = "testvalue" - pt1, _ := telegraf.NewMetric( + pt3, _ := telegraf.NewMetric( "test_point_3", tags, map[string]interface{}{"value": 0.0}) - pt2, _ := telegraf.NewMetric( + pt4, _ := telegraf.NewMetric( "test_point_4", tags, map[string]interface{}{"value": 1.0}) - var metrics = []telegraf.Metric{ - pt1, - pt2, + metrics = []telegraf.Metric{ + pt3, + pt4, } require.NoError(t, pTesting.Write(metrics)) - expected := []struct { + expected2 := []struct { name string value float64 }{ @@ -85,16 +79,9 @@ func TestPrometheusWritePointTag(t *testing.T) { {"test_point_4", 1.0}, } - var acc testutil.Accumulator - require.NoError(t, p.Gather(&acc)) - for _, e := range expected { + for _, e := range expected2 { acc.AssertContainsFields(t, "prometheus_"+e.name, map[string]interface{}{"value": e.value}) } } - -func init() { - pTesting = &PrometheusClient{Listen: "localhost:9126"} - pTesting.Start() -}