403 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			403 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Go
		
	
	
	
| package prometheus
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/influxdata/telegraf"
 | |
| 	inputs "github.com/influxdata/telegraf/plugins/inputs/prometheus"
 | |
| 	"github.com/influxdata/telegraf/testutil"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestMetricVersion1(t *testing.T) {
 | |
| 	Logger := testutil.Logger{Name: "outputs.prometheus_client"}
 | |
| 	tests := []struct {
 | |
| 		name     string
 | |
| 		output   *PrometheusClient
 | |
| 		metrics  []telegraf.Metric
 | |
| 		expected []byte
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "simple",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.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 untyped",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu_time_idle",
 | |
| 					map[string]string{
 | |
| 						"host": "example.org",
 | |
| 					},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 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 counter",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu_time_idle",
 | |
| 					map[string]string{
 | |
| 						"host": "example.org",
 | |
| 					},
 | |
| 					map[string]interface{}{
 | |
| 						"counter": 42.0,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 					telegraf.Counter,
 | |
| 				),
 | |
| 			},
 | |
| 			expected: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle counter
 | |
| cpu_time_idle{host="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "replace characters when using string as label",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				StringAsLabel:     true,
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu_time_idle",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"host:name": "example.org",
 | |
| 						"counter":   42.0,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 					telegraf.Counter,
 | |
| 				),
 | |
| 			},
 | |
| 			expected: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle counter
 | |
| cpu_time_idle{host_name="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "prometheus gauge",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu_time_idle",
 | |
| 					map[string]string{
 | |
| 						"host": "example.org",
 | |
| 					},
 | |
| 					map[string]interface{}{
 | |
| 						"gauge": 42.0,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 					telegraf.Gauge,
 | |
| 				),
 | |
| 			},
 | |
| 			expected: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle gauge
 | |
| cpu_time_idle{host="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "prometheus histogram",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"http_request_duration_seconds",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"sum":   53423,
 | |
| 						"0.05":  24054,
 | |
| 						"0.1":   33444,
 | |
| 						"0.2":   100392,
 | |
| 						"0.5":   129389,
 | |
| 						"1":     133988,
 | |
| 						"+Inf":  144320,
 | |
| 						"count": 144320,
 | |
| 					},
 | |
| 					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: "prometheus summary",
 | |
| 			output: &PrometheusClient{
 | |
| 				Listen:            ":0",
 | |
| 				MetricVersion:     1,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 				Path:              "/metrics",
 | |
| 				Log:               Logger,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"rpc_duration_seconds",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"0.01":  3102,
 | |
| 						"0.05":  3272,
 | |
| 						"0.5":   4773,
 | |
| 						"0.9":   9001,
 | |
| 						"0.99":  76656,
 | |
| 						"count": 2693,
 | |
| 						"sum":   17560473,
 | |
| 					},
 | |
| 					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
 | |
| `),
 | |
| 		},
 | |
| 	}
 | |
| 	for _, tt := range tests {
 | |
| 		t.Run(tt.name, func(t *testing.T) {
 | |
| 			err := tt.output.Init()
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			err = tt.output.Connect()
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			defer func() {
 | |
| 				err := tt.output.Close()
 | |
| 				require.NoError(t, err)
 | |
| 			}()
 | |
| 
 | |
| 			err = tt.output.Write(tt.metrics)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			resp, err := http.Get(tt.output.URL())
 | |
| 			require.NoError(t, err)
 | |
| 			require.Equal(t, http.StatusOK, resp.StatusCode)
 | |
| 			defer resp.Body.Close()
 | |
| 			body, err := ioutil.ReadAll(resp.Body)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			require.Equal(t,
 | |
| 				strings.TrimSpace(string(tt.expected)),
 | |
| 				strings.TrimSpace(string(body)))
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestRoundTripMetricVersion1(t *testing.T) {
 | |
| 	Logger := testutil.Logger{Name: "outputs.prometheus_client"}
 | |
| 	tests := []struct {
 | |
| 		name string
 | |
| 		data []byte
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "untyped",
 | |
| 			data: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle untyped
 | |
| cpu_time_idle{host="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "counter",
 | |
| 			data: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle counter
 | |
| cpu_time_idle{host="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "gauge",
 | |
| 			data: []byte(`
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle gauge
 | |
| cpu_time_idle{host="example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "multi",
 | |
| 			data: []byte(`
 | |
| # HELP cpu_time_guest Telegraf collected metric
 | |
| # TYPE cpu_time_guest gauge
 | |
| cpu_time_guest{host="one.example.org"} 42
 | |
| cpu_time_guest{host="two.example.org"} 42
 | |
| # HELP cpu_time_idle Telegraf collected metric
 | |
| # TYPE cpu_time_idle gauge
 | |
| cpu_time_idle{host="one.example.org"} 42
 | |
| cpu_time_idle{host="two.example.org"} 42
 | |
| `),
 | |
| 		},
 | |
| 		{
 | |
| 			name: "histogram",
 | |
| 			data: []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: "summary",
 | |
| 			data: []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
 | |
| `),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	ts := httptest.NewServer(http.NotFoundHandler())
 | |
| 	defer ts.Close()
 | |
| 
 | |
| 	url := fmt.Sprintf("http://%s", ts.Listener.Addr())
 | |
| 
 | |
| 	for _, tt := range tests {
 | |
| 		t.Run(tt.name, func(t *testing.T) {
 | |
| 			ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 				w.WriteHeader(http.StatusOK)
 | |
| 				w.Write(tt.data)
 | |
| 			})
 | |
| 
 | |
| 			input := &inputs.Prometheus{
 | |
| 				URLs:          []string{url},
 | |
| 				URLTag:        "",
 | |
| 				MetricVersion: 1,
 | |
| 			}
 | |
| 			var acc testutil.Accumulator
 | |
| 			err := input.Start(&acc)
 | |
| 			require.NoError(t, err)
 | |
| 			err = input.Gather(&acc)
 | |
| 			require.NoError(t, err)
 | |
| 			input.Stop()
 | |
| 
 | |
| 			metrics := acc.GetTelegrafMetrics()
 | |
| 
 | |
| 			output := &PrometheusClient{
 | |
| 				Listen:            "127.0.0.1:0",
 | |
| 				Path:              defaultPath,
 | |
| 				MetricVersion:     1,
 | |
| 				Log:               Logger,
 | |
| 				CollectorsExclude: []string{"gocollector", "process"},
 | |
| 			}
 | |
| 			err = output.Init()
 | |
| 			require.NoError(t, err)
 | |
| 			err = output.Connect()
 | |
| 			require.NoError(t, err)
 | |
| 			defer func() {
 | |
| 				err = output.Close()
 | |
| 				require.NoError(t, err)
 | |
| 			}()
 | |
| 			err = output.Write(metrics)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			resp, err := http.Get(output.URL())
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			actual, err := ioutil.ReadAll(resp.Body)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			require.Equal(t,
 | |
| 				strings.TrimSpace(string(tt.data)),
 | |
| 				strings.TrimSpace(string(actual)))
 | |
| 		})
 | |
| 	}
 | |
| }
 |