telegraf/plugins/serializers/prometheus/prometheus_test.go

668 lines
15 KiB
Go

package prometheus
import (
"strings"
"testing"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/require"
)
func TestSerialize(t *testing.T) {
tests := []struct {
name string
config FormatConfig
metric telegraf.Metric
expected []byte
}{
{
name: "simple",
metric: testutil.MustMetric(
"cpu",
map[string]string{
"host": "example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host="example.org"} 42
`),
},
{
name: "prometheus input untyped",
metric: testutil.MustMetric(
"prometheus",
map[string]string{
"code": "400",
"method": "post",
},
map[string]interface{}{
"http_requests_total": 3.0,
},
time.Unix(0, 0),
telegraf.Untyped,
),
expected: []byte(`
# HELP http_requests_total Telegraf collected metric
# TYPE http_requests_total untyped
http_requests_total{code="400",method="post"} 3
`),
},
{
name: "prometheus input counter",
metric: testutil.MustMetric(
"prometheus",
map[string]string{
"code": "400",
"method": "post",
},
map[string]interface{}{
"http_requests_total": 3.0,
},
time.Unix(0, 0),
telegraf.Counter,
),
expected: []byte(`
# HELP http_requests_total Telegraf collected metric
# TYPE http_requests_total counter
http_requests_total{code="400",method="post"} 3
`),
},
{
name: "prometheus input gauge",
metric: testutil.MustMetric(
"prometheus",
map[string]string{
"code": "400",
"method": "post",
},
map[string]interface{}{
"http_requests_total": 3.0,
},
time.Unix(0, 0),
telegraf.Gauge,
),
expected: []byte(`
# HELP http_requests_total Telegraf collected metric
# TYPE http_requests_total gauge
http_requests_total{code="400",method="post"} 3
`),
},
{
name: "prometheus input histogram no buckets",
metric: testutil.MustMetric(
"prometheus",
map[string]string{},
map[string]interface{}{
"http_request_duration_seconds_sum": 53423,
"http_request_duration_seconds_count": 144320,
},
time.Unix(0, 0),
telegraf.Histogram,
),
expected: []byte(`
`),
},
{
name: "prometheus input histogram only bucket",
metric: testutil.MustMetric(
"prometheus",
map[string]string{
"le": "0.5",
},
map[string]interface{}{
"http_request_duration_seconds_bucket": 129389.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
expected: []byte(`
# HELP http_request_duration_seconds Telegraf collected metric
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="+Inf"} 0
http_request_duration_seconds_sum 0
http_request_duration_seconds_count 0
`),
},
{
name: "simple with timestamp",
config: FormatConfig{
TimestampExport: ExportTimestamp,
},
metric: testutil.MustMetric(
"cpu",
map[string]string{
"host": "example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(1574279268, 0),
),
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host="example.org"} 42 1574279268000
`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, err := NewSerializer(FormatConfig{
MetricSortOrder: SortMetrics,
TimestampExport: tt.config.TimestampExport,
StringHandling: tt.config.StringHandling,
})
require.NoError(t, err)
actual, err := s.Serialize(tt.metric)
require.NoError(t, err)
require.Equal(t, strings.TrimSpace(string(tt.expected)),
strings.TrimSpace(string(actual)))
})
}
}
func TestSerializeBatch(t *testing.T) {
tests := []struct {
name string
config FormatConfig
metrics []telegraf.Metric
expected []byte
}{
{
name: "simple",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"host": "one.example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
testutil.MustMetric(
"cpu",
map[string]string{
"host": "two.example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host="one.example.org"} 42
cpu_time_idle{host="two.example.org"} 42
`),
},
{
name: "multiple metric families",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"host": "one.example.org",
},
map[string]interface{}{
"time_idle": 42.0,
"time_guest": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_guest Telegraf collected metric
# TYPE cpu_time_guest untyped
cpu_time_guest{host="one.example.org"} 42
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host="one.example.org"} 42
`),
},
{
name: "histogram",
metrics: []telegraf.Metric{
testutil.MustMetric(
"prometheus",
map[string]string{},
map[string]interface{}{
"http_request_duration_seconds_sum": 53423,
"http_request_duration_seconds_count": 144320,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "0.05"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 24054.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "0.1"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 33444.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "0.2"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 100392.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "0.5"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 129389.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "1.0"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 133988.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
testutil.MustMetric(
"prometheus",
map[string]string{"le": "+Inf"},
map[string]interface{}{
"http_request_duration_seconds_bucket": 144320.0,
},
time.Unix(0, 0),
telegraf.Histogram,
),
},
expected: []byte(`
# HELP http_request_duration_seconds Telegraf collected metric
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.05"} 24054
http_request_duration_seconds_bucket{le="0.1"} 33444
http_request_duration_seconds_bucket{le="0.2"} 100392
http_request_duration_seconds_bucket{le="0.5"} 129389
http_request_duration_seconds_bucket{le="1"} 133988
http_request_duration_seconds_bucket{le="+Inf"} 144320
http_request_duration_seconds_sum 53423
http_request_duration_seconds_count 144320
`),
},
{
name: "",
metrics: []telegraf.Metric{
testutil.MustMetric(
"prometheus",
map[string]string{},
map[string]interface{}{
"rpc_duration_seconds_sum": 1.7560473e+07,
"rpc_duration_seconds_count": 2693,
},
time.Unix(0, 0),
telegraf.Summary,
),
testutil.MustMetric(
"prometheus",
map[string]string{"quantile": "0.01"},
map[string]interface{}{
"rpc_duration_seconds": 3102.0,
},
time.Unix(0, 0),
telegraf.Summary,
),
testutil.MustMetric(
"prometheus",
map[string]string{"quantile": "0.05"},
map[string]interface{}{
"rpc_duration_seconds": 3272.0,
},
time.Unix(0, 0),
telegraf.Summary,
),
testutil.MustMetric(
"prometheus",
map[string]string{"quantile": "0.5"},
map[string]interface{}{
"rpc_duration_seconds": 4773.0,
},
time.Unix(0, 0),
telegraf.Summary,
),
testutil.MustMetric(
"prometheus",
map[string]string{"quantile": "0.9"},
map[string]interface{}{
"rpc_duration_seconds": 9001.0,
},
time.Unix(0, 0),
telegraf.Summary,
),
testutil.MustMetric(
"prometheus",
map[string]string{"quantile": "0.99"},
map[string]interface{}{
"rpc_duration_seconds": 76656.0,
},
time.Unix(0, 0),
telegraf.Summary,
),
},
expected: []byte(`
# HELP rpc_duration_seconds Telegraf collected metric
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.01"} 3102
rpc_duration_seconds{quantile="0.05"} 3272
rpc_duration_seconds{quantile="0.5"} 4773
rpc_duration_seconds{quantile="0.9"} 9001
rpc_duration_seconds{quantile="0.99"} 76656
rpc_duration_seconds_sum 1.7560473e+07
rpc_duration_seconds_count 2693
`),
},
{
name: "newer sample",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"time_idle": 43.0,
},
time.Unix(1, 0),
),
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle 43
`),
},
{
name: "colons are not replaced in metric name from measurement",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu::xyzzy",
map[string]string{},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu::xyzzy_time_idle Telegraf collected metric
# TYPE cpu::xyzzy_time_idle untyped
cpu::xyzzy_time_idle 42
`),
},
{
name: "colons are not replaced in metric name from field",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"time:idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time:idle Telegraf collected metric
# TYPE cpu_time:idle untyped
cpu_time:idle 42
`),
},
{
name: "invalid label",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"host-name": "example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host_name="example.org"} 42
`),
},
{
name: "colons are replaced in label name",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"host:name": "example.org",
},
map[string]interface{}{
"time_idle": 42.0,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host_name="example.org"} 42
`),
},
{
name: "discard strings",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"time_idle": 42.0,
"cpu": "cpu0",
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle 42
`),
},
{
name: "string as label",
config: FormatConfig{
StringHandling: StringAsLabel,
},
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"time_idle": 42.0,
"cpu": "cpu0",
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{cpu="cpu0"} 42
`),
},
{
name: "string as label duplicate tag",
config: FormatConfig{
StringHandling: StringAsLabel,
},
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"cpu": "cpu0",
},
map[string]interface{}{
"time_idle": 42.0,
"cpu": "cpu1",
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{cpu="cpu0"} 42
`),
},
{
name: "replace characters when using string as label",
config: FormatConfig{
StringHandling: StringAsLabel,
},
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"host:name": "example.org",
"time_idle": 42.0,
},
time.Unix(1574279268, 0),
),
},
expected: []byte(`
# HELP cpu_time_idle Telegraf collected metric
# TYPE cpu_time_idle untyped
cpu_time_idle{host_name="example.org"} 42
`),
},
{
name: "multiple fields grouping",
metrics: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"cpu": "cpu0",
},
map[string]interface{}{
"time_guest": 8106.04,
"time_system": 26271.4,
"time_user": 92904.33,
},
time.Unix(0, 0),
),
testutil.MustMetric(
"cpu",
map[string]string{
"cpu": "cpu1",
},
map[string]interface{}{
"time_guest": 8181.63,
"time_system": 25351.49,
"time_user": 96912.57,
},
time.Unix(0, 0),
),
testutil.MustMetric(
"cpu",
map[string]string{
"cpu": "cpu2",
},
map[string]interface{}{
"time_guest": 7470.04,
"time_system": 24998.43,
"time_user": 96034.08,
},
time.Unix(0, 0),
),
testutil.MustMetric(
"cpu",
map[string]string{
"cpu": "cpu3",
},
map[string]interface{}{
"time_guest": 7517.95,
"time_system": 24970.82,
"time_user": 94148,
},
time.Unix(0, 0),
),
},
expected: []byte(`
# HELP cpu_time_guest Telegraf collected metric
# TYPE cpu_time_guest untyped
cpu_time_guest{cpu="cpu0"} 8106.04
cpu_time_guest{cpu="cpu1"} 8181.63
cpu_time_guest{cpu="cpu2"} 7470.04
cpu_time_guest{cpu="cpu3"} 7517.95
# HELP cpu_time_system Telegraf collected metric
# TYPE cpu_time_system untyped
cpu_time_system{cpu="cpu0"} 26271.4
cpu_time_system{cpu="cpu1"} 25351.49
cpu_time_system{cpu="cpu2"} 24998.43
cpu_time_system{cpu="cpu3"} 24970.82
# HELP cpu_time_user Telegraf collected metric
# TYPE cpu_time_user untyped
cpu_time_user{cpu="cpu0"} 92904.33
cpu_time_user{cpu="cpu1"} 96912.57
cpu_time_user{cpu="cpu2"} 96034.08
cpu_time_user{cpu="cpu3"} 94148
`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, err := NewSerializer(FormatConfig{
MetricSortOrder: SortMetrics,
TimestampExport: tt.config.TimestampExport,
StringHandling: tt.config.StringHandling,
})
require.NoError(t, err)
actual, err := s.SerializeBatch(tt.metrics)
require.NoError(t, err)
require.Equal(t,
strings.TrimSpace(string(tt.expected)),
strings.TrimSpace(string(actual)))
})
}
}