Skip to content

Commit

Permalink
feat(prometheus): Configurable Registerer
Browse files Browse the repository at this point in the history
Add the ability to configure the `prometheus.Registerer`, allowing customisation of the registry metrics are added to.
  • Loading branch information
Matthew Palmer authored and aldas committed Jul 28, 2022
1 parent d0a6a6e commit 18f2b66
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 18 deletions.
4 changes: 3 additions & 1 deletion prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ type Prometheus struct {
MetricsPath string
Subsystem string
Skipper middleware.Skipper
Registerer prometheus.Registerer

RequestCounterURLLabelMappingFunc RequestCounterLabelMappingFunc
RequestCounterHostLabelMappingFunc RequestCounterLabelMappingFunc
Expand Down Expand Up @@ -192,6 +193,7 @@ func NewPrometheus(subsystem string, skipper middleware.Skipper, customMetricsLi
RequestCounterHostLabelMappingFunc: func(c echo.Context) string {
return c.Request().Host
},
Registerer: prometheus.DefaultRegisterer,
}

p.registerMetrics(subsystem)
Expand Down Expand Up @@ -367,7 +369,7 @@ func (p *Prometheus) registerMetrics(subsystem string) {

for _, metricDef := range p.MetricsList {
metric := NewMetric(metricDef, subsystem)
if err := prometheus.Register(metric); err != nil {
if err := p.Registerer.Register(metric); err != nil {
log.Errorf("%s could not be registered in Prometheus: %v", metricDef.Name, err)
}
switch metricDef {
Expand Down
27 changes: 10 additions & 17 deletions prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,21 @@ import (
"github.com/stretchr/testify/assert"
)

func unregister(p *Prometheus) {
prometheus.Unregister(p.reqCnt)
prometheus.Unregister(p.reqDur)
prometheus.Unregister(p.reqSz)
prometheus.Unregister(p.resSz)
}

func TestPrometheus_Use(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

assert.Equal(t, 1, len(e.Routes()), "only one route should be added")
assert.NotNil(t, e, "the engine should not be empty")
assert.Equal(t, e.Routes()[0].Path, p.MetricsPath, "the path should match the metrics path")
unregister(p)
}

func TestPrometheus_Buckets(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

path := "/ping"
Expand All @@ -51,24 +45,24 @@ func TestPrometheus_Buckets(t *testing.T) {
assert.NotRegexp(t, "request_size_bytes.*le=\"0.005\"", r.Body.String(), "request should NOT have time bucket (like, 0.005s)")
})

unregister(p)
}

func TestPath(t *testing.T) {
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
assert.Equal(t, p.MetricsPath, defaultMetricPath, "no usage of path should yield default path")
unregister(p)
}

func TestSubsystem(t *testing.T) {
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
assert.Equal(t, p.Subsystem, "echo", "subsystem should be default")
unregister(p)
}

func TestUse(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()

g := gofight.New()
g.GET(p.MetricsPath).Run(e, func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
Expand All @@ -80,7 +74,6 @@ func TestUse(t *testing.T) {
g.GET(p.MetricsPath).Run(e, func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
assert.Equal(t, http.StatusOK, r.Code)
})
unregister(p)
}

func TestIgnore(t *testing.T) {
Expand All @@ -95,6 +88,7 @@ func TestIgnore(t *testing.T) {
return false
}
p := NewPrometheus("echo", ignore)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

g := gofight.New()
Expand All @@ -111,12 +105,12 @@ func TestIgnore(t *testing.T) {
assert.NotContains(t, r.Body.String(), fmt.Sprintf("%s_requests_total", p.Subsystem))
assert.NotContains(t, r.Body.String(), lipath, "ignored path must not be present")
})
unregister(p)
}

func TestMetricsGenerated(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

path := "/ping"
Expand All @@ -130,38 +124,38 @@ func TestMetricsGenerated(t *testing.T) {
assert.Contains(t, r.Body.String(), fmt.Sprintf("%s_requests_total", p.Subsystem))
assert.Contains(t, r.Body.String(), lpath, "path must be present")
})
unregister(p)
}

func TestMetricsPathIgnored(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

g := gofight.New()
g.GET(p.MetricsPath).Run(e, func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
assert.Equal(t, http.StatusOK, r.Code)
assert.NotContains(t, r.Body.String(), fmt.Sprintf("%s_requests_total", p.Subsystem))
})
unregister(p)
}

func TestMetricsPushGateway(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

g := gofight.New()
g.GET(p.MetricsPath).Run(e, func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {
assert.Equal(t, http.StatusOK, r.Code)
assert.NotContains(t, r.Body.String(), fmt.Sprintf("%s_request_duration", p.Subsystem))
})
unregister(p)
}

func TestMetricsForErrors(t *testing.T) {
e := echo.New()
p := NewPrometheus("echo", nil)
p.Registerer = prometheus.NewRegistry()
p.Use(e)

e.GET("/handler_for_ok", func(c echo.Context) error {
Expand Down Expand Up @@ -190,5 +184,4 @@ func TestMetricsForErrors(t *testing.T) {
assert.Contains(t, body, `echo_requests_total{code="409",host="",method="GET",url="/handler_for_nok"} 2`)
assert.Contains(t, body, `echo_requests_total{code="502",host="",method="GET",url="/handler_for_error"} 1`)
})
unregister(p)
}

0 comments on commit 18f2b66

Please sign in to comment.