2015-06-20 12:38:01 +00:00
|
|
|
package prometheus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-02-10 22:18:30 +00:00
|
|
|
"math"
|
2015-06-20 12:38:01 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2017-09-18 22:06:11 +00:00
|
|
|
"net/url"
|
2015-06-20 12:38:01 +00:00
|
|
|
"testing"
|
2017-03-29 22:04:29 +00:00
|
|
|
"time"
|
2015-06-20 12:38:01 +00:00
|
|
|
|
2020-02-10 22:18:30 +00:00
|
|
|
"github.com/influxdata/telegraf"
|
2016-01-20 18:57:35 +00:00
|
|
|
"github.com/influxdata/telegraf/testutil"
|
2015-06-20 12:38:01 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
const sampleTextFormat = `# HELP go_gc_duration_seconds A summary of the GC invocation durations.
|
|
|
|
# TYPE go_gc_duration_seconds summary
|
|
|
|
go_gc_duration_seconds{quantile="0"} 0.00010425500000000001
|
|
|
|
go_gc_duration_seconds{quantile="0.25"} 0.000139108
|
|
|
|
go_gc_duration_seconds{quantile="0.5"} 0.00015749400000000002
|
|
|
|
go_gc_duration_seconds{quantile="0.75"} 0.000331463
|
|
|
|
go_gc_duration_seconds{quantile="1"} 0.000667154
|
|
|
|
go_gc_duration_seconds_sum 0.0018183950000000002
|
|
|
|
go_gc_duration_seconds_count 7
|
|
|
|
# HELP go_goroutines Number of goroutines that currently exist.
|
|
|
|
# TYPE go_goroutines gauge
|
|
|
|
go_goroutines 15
|
2017-03-29 22:04:29 +00:00
|
|
|
# HELP test_metric An untyped metric with a timestamp
|
|
|
|
# TYPE test_metric untyped
|
|
|
|
test_metric{label="value"} 1.0 1490802350000
|
2015-06-20 12:38:01 +00:00
|
|
|
`
|
2019-11-21 04:53:57 +00:00
|
|
|
const sampleSummaryTextFormat = `# HELP go_gc_duration_seconds A summary of the GC invocation durations.
|
|
|
|
# TYPE go_gc_duration_seconds summary
|
|
|
|
go_gc_duration_seconds{quantile="0"} 0.00010425500000000001
|
|
|
|
go_gc_duration_seconds{quantile="0.25"} 0.000139108
|
|
|
|
go_gc_duration_seconds{quantile="0.5"} 0.00015749400000000002
|
|
|
|
go_gc_duration_seconds{quantile="0.75"} 0.000331463
|
|
|
|
go_gc_duration_seconds{quantile="1"} 0.000667154
|
|
|
|
go_gc_duration_seconds_sum 0.0018183950000000002
|
|
|
|
go_gc_duration_seconds_count 7
|
|
|
|
`
|
|
|
|
const sampleGaugeTextFormat = `
|
|
|
|
# HELP go_goroutines Number of goroutines that currently exist.
|
|
|
|
# TYPE go_goroutines gauge
|
|
|
|
go_goroutines 15 1490802350000
|
|
|
|
`
|
2015-06-20 12:38:01 +00:00
|
|
|
|
|
|
|
func TestPrometheusGeneratesMetrics(t *testing.T) {
|
2015-08-04 22:09:59 +00:00
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, sampleTextFormat)
|
|
|
|
}))
|
2015-06-20 12:38:01 +00:00
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
2019-11-21 04:53:57 +00:00
|
|
|
Log: testutil.Logger{},
|
|
|
|
URLs: []string{ts.URL},
|
|
|
|
URLTag: "url",
|
2015-06-20 12:38:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
2017-04-24 18:13:26 +00:00
|
|
|
err := acc.GatherError(p.Gather)
|
2015-06-20 12:38:01 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2016-03-01 16:12:23 +00:00
|
|
|
assert.True(t, acc.HasFloatField("go_gc_duration_seconds", "count"))
|
|
|
|
assert.True(t, acc.HasFloatField("go_goroutines", "gauge"))
|
2017-03-29 22:04:29 +00:00
|
|
|
assert.True(t, acc.HasFloatField("test_metric", "value"))
|
|
|
|
assert.True(t, acc.HasTimestamp("test_metric", time.Unix(1490802350, 0)))
|
2017-09-18 22:06:11 +00:00
|
|
|
assert.False(t, acc.HasTag("test_metric", "address"))
|
2018-11-03 00:51:40 +00:00
|
|
|
assert.True(t, acc.TagValue("test_metric", "url") == ts.URL+"/metrics")
|
2017-09-18 22:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPrometheusGeneratesMetricsWithHostNameTag(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, sampleTextFormat)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
2019-09-23 22:39:50 +00:00
|
|
|
Log: testutil.Logger{},
|
2017-09-18 22:06:11 +00:00
|
|
|
KubernetesServices: []string{ts.URL},
|
2019-11-21 04:53:57 +00:00
|
|
|
URLTag: "url",
|
2017-09-18 22:06:11 +00:00
|
|
|
}
|
|
|
|
u, _ := url.Parse(ts.URL)
|
|
|
|
tsAddress := u.Hostname()
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
err := acc.GatherError(p.Gather)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.True(t, acc.HasFloatField("go_gc_duration_seconds", "count"))
|
|
|
|
assert.True(t, acc.HasFloatField("go_goroutines", "gauge"))
|
|
|
|
assert.True(t, acc.HasFloatField("test_metric", "value"))
|
|
|
|
assert.True(t, acc.HasTimestamp("test_metric", time.Unix(1490802350, 0)))
|
|
|
|
assert.True(t, acc.TagValue("test_metric", "address") == tsAddress)
|
2017-09-23 00:26:19 +00:00
|
|
|
assert.True(t, acc.TagValue("test_metric", "url") == ts.URL)
|
2017-09-18 22:06:11 +00:00
|
|
|
}
|
2017-03-29 22:04:29 +00:00
|
|
|
|
2017-09-18 22:06:11 +00:00
|
|
|
func TestPrometheusGeneratesMetricsAlthoughFirstDNSFails(t *testing.T) {
|
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("Skipping integration test in short mode")
|
|
|
|
}
|
|
|
|
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, sampleTextFormat)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
2019-09-23 22:39:50 +00:00
|
|
|
Log: testutil.Logger{},
|
2018-02-05 19:16:00 +00:00
|
|
|
URLs: []string{ts.URL},
|
2017-09-18 22:06:11 +00:00
|
|
|
KubernetesServices: []string{"http://random.telegraf.local:88/metrics"},
|
|
|
|
}
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
err := acc.GatherError(p.Gather)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.True(t, acc.HasFloatField("go_gc_duration_seconds", "count"))
|
|
|
|
assert.True(t, acc.HasFloatField("go_goroutines", "gauge"))
|
|
|
|
assert.True(t, acc.HasFloatField("test_metric", "value"))
|
|
|
|
assert.True(t, acc.HasTimestamp("test_metric", time.Unix(1490802350, 0)))
|
2015-06-20 12:38:01 +00:00
|
|
|
}
|
2019-11-21 04:53:57 +00:00
|
|
|
|
|
|
|
func TestPrometheusGeneratesSummaryMetricsV2(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, sampleSummaryTextFormat)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
|
|
|
URLs: []string{ts.URL},
|
|
|
|
URLTag: "url",
|
|
|
|
MetricVersion: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
err := acc.GatherError(p.Gather)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.True(t, acc.TagSetValue("prometheus", "quantile") == "0")
|
|
|
|
assert.True(t, acc.HasFloatField("prometheus", "go_gc_duration_seconds_sum"))
|
|
|
|
assert.True(t, acc.HasFloatField("prometheus", "go_gc_duration_seconds_count"))
|
|
|
|
assert.True(t, acc.TagValue("prometheus", "url") == ts.URL+"/metrics")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-02-10 22:18:30 +00:00
|
|
|
func TestSummaryMayContainNaN(t *testing.T) {
|
|
|
|
const data = `# HELP go_gc_duration_seconds A summary of the GC invocation durations.
|
|
|
|
# TYPE go_gc_duration_seconds summary
|
|
|
|
go_gc_duration_seconds{quantile="0"} NaN
|
|
|
|
go_gc_duration_seconds{quantile="1"} NaN
|
|
|
|
go_gc_duration_seconds_sum 42.0
|
|
|
|
go_gc_duration_seconds_count 42
|
|
|
|
`
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, data)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
|
|
|
URLs: []string{ts.URL},
|
|
|
|
URLTag: "",
|
|
|
|
MetricVersion: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
err := p.Gather(&acc)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expected := []telegraf.Metric{
|
|
|
|
testutil.MustMetric(
|
|
|
|
"prometheus",
|
|
|
|
map[string]string{
|
|
|
|
"quantile": "0",
|
|
|
|
},
|
|
|
|
map[string]interface{}{
|
|
|
|
"go_gc_duration_seconds": math.NaN(),
|
|
|
|
},
|
|
|
|
time.Unix(0, 0),
|
|
|
|
telegraf.Summary,
|
|
|
|
),
|
|
|
|
testutil.MustMetric(
|
|
|
|
"prometheus",
|
|
|
|
map[string]string{
|
|
|
|
"quantile": "1",
|
|
|
|
},
|
|
|
|
map[string]interface{}{
|
|
|
|
"go_gc_duration_seconds": math.NaN(),
|
|
|
|
},
|
|
|
|
time.Unix(0, 0),
|
|
|
|
telegraf.Summary,
|
|
|
|
),
|
|
|
|
testutil.MustMetric(
|
|
|
|
"prometheus",
|
|
|
|
map[string]string{},
|
|
|
|
map[string]interface{}{
|
|
|
|
"go_gc_duration_seconds_sum": 42.0,
|
|
|
|
"go_gc_duration_seconds_count": 42.0,
|
|
|
|
},
|
|
|
|
time.Unix(0, 0),
|
|
|
|
telegraf.Summary,
|
|
|
|
),
|
|
|
|
}
|
|
|
|
|
|
|
|
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics(),
|
|
|
|
testutil.IgnoreTime(), testutil.SortMetrics())
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:53:57 +00:00
|
|
|
func TestPrometheusGeneratesGaugeMetricsV2(t *testing.T) {
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fmt.Fprintln(w, sampleGaugeTextFormat)
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
|
|
|
|
p := &Prometheus{
|
|
|
|
URLs: []string{ts.URL},
|
|
|
|
URLTag: "url",
|
|
|
|
MetricVersion: 2,
|
|
|
|
}
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
|
|
|
err := acc.GatherError(p.Gather)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.True(t, acc.HasFloatField("prometheus", "go_goroutines"))
|
|
|
|
assert.True(t, acc.TagValue("prometheus", "url") == ts.URL+"/metrics")
|
|
|
|
assert.True(t, acc.HasTimestamp("prometheus", time.Unix(1490802350, 0)))
|
|
|
|
}
|