Fix metrics registering

This commit is contained in:
Matevz Mihalic 2017-03-08 15:17:07 +01:00 committed by Emile Vauge
parent c876462eb0
commit f324983946
No known key found for this signature in database
GPG key ID: D808B4C167352E59
2 changed files with 110 additions and 3 deletions

View file

@ -32,7 +32,8 @@ func (p *Prometheus) getLatencyHistogram() metrics.Histogram {
// NewPrometheus returns a new prometheus Metrics implementation.
func NewPrometheus(name string, config *types.Prometheus) *Prometheus {
var m Prometheus
m.reqsCounter = prometheus.NewCounterFrom(
cv := stdprometheus.NewCounterVec(
stdprometheus.CounterOpts{
Name: reqsName,
Help: "How many HTTP requests processed, partitioned by status code and method.",
@ -41,6 +42,17 @@ func NewPrometheus(name string, config *types.Prometheus) *Prometheus {
[]string{"code", "method"},
)
err := stdprometheus.Register(cv)
if err != nil {
e, ok := err.(stdprometheus.AlreadyRegisteredError)
if !ok {
panic(err)
}
m.reqsCounter = prometheus.NewCounter(e.ExistingCollector.(*stdprometheus.CounterVec))
} else {
m.reqsCounter = prometheus.NewCounter(cv)
}
var buckets []float64
if config.Buckets != nil {
buckets = config.Buckets
@ -48,7 +60,7 @@ func NewPrometheus(name string, config *types.Prometheus) *Prometheus {
buckets = []float64{0.1, 0.3, 1.2, 5}
}
m.latencyHistogram = prometheus.NewHistogramFrom(
hv := stdprometheus.NewHistogramVec(
stdprometheus.HistogramOpts{
Name: latencyName,
Help: "How long it took to process the request.",
@ -57,6 +69,18 @@ func NewPrometheus(name string, config *types.Prometheus) *Prometheus {
},
[]string{},
)
err = stdprometheus.Register(hv)
if err != nil {
e, ok := err.(stdprometheus.AlreadyRegisteredError)
if !ok {
panic(err)
}
m.latencyHistogram = prometheus.NewHistogram(e.ExistingCollector.(*stdprometheus.HistogramVec))
} else {
m.latencyHistogram = prometheus.NewHistogram(hv)
}
return &m
}

View file

@ -9,10 +9,19 @@ import (
"github.com/codegangsta/negroni"
"github.com/containous/traefik/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
dto "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/assert"
)
func TestPrometheus(t *testing.T) {
metricsFamily, err := prometheus.DefaultGatherer.Gather()
if err != nil {
t.Fatalf("could not gather metrics family: %s", err)
}
initialMetricsFamilyCount := len(metricsFamily)
recorder := httptest.NewRecorder()
n := negroni.New()
@ -42,6 +51,80 @@ func TestPrometheus(t *testing.T) {
t.Errorf("body does not contain request total entry '%s'", reqsName)
}
if !strings.Contains(body, latencyName) {
t.Errorf("body does not contain request duration entry '%s'", reqsName)
t.Errorf("body does not contain request duration entry '%s'", latencyName)
}
// Register the same metrics again
metricsMiddlewareBackend = NewMetricsWrapper(NewPrometheus("test", &types.Prometheus{}))
n = negroni.New()
n.Use(metricsMiddlewareBackend)
n.UseHandler(r)
n.ServeHTTP(recorder, req2)
metricsFamily, err = prometheus.DefaultGatherer.Gather()
if err != nil {
t.Fatalf("could not gather metrics family: %s", err)
}
tests := []struct {
name string
labels map[string]string
assert func(*dto.MetricFamily)
}{
{
name: reqsName,
labels: map[string]string{
"code": "200",
"method": "GET",
"service": "test",
},
assert: func(family *dto.MetricFamily) {
cv := uint(family.Metric[0].Counter.GetValue())
if cv != 3 {
t.Errorf("gathered metrics do not contain correct value for total requests, got %d", cv)
}
},
},
{
name: latencyName,
labels: map[string]string{
"service": "test",
},
assert: func(family *dto.MetricFamily) {
sc := family.Metric[0].Histogram.GetSampleCount()
if sc != 3 {
t.Errorf("gathered metrics do not contain correct sample count for request duration, got %d", sc)
}
},
},
}
assert.Equal(t, len(tests), len(metricsFamily)-initialMetricsFamilyCount, "gathered traefic metrics count does not match tests count")
for _, test := range tests {
family := findMetricFamily(test.name, metricsFamily)
if family == nil {
t.Errorf("gathered metrics do not contain '%s'", test.name)
continue
}
for _, label := range family.Metric[0].Label {
val, ok := test.labels[*label.Name]
if !ok {
t.Errorf("'%s' metric contains unexpected label '%s'", test.name, label)
} else if val != *label.Value {
t.Errorf("label '%s' in metric '%s' has wrong value '%s'", label, test.name, *label.Value)
}
}
test.assert(family)
}
}
func findMetricFamily(name string, families []*dto.MetricFamily) *dto.MetricFamily {
for _, family := range families {
if family.GetName() == name {
return family
}
}
return nil
}