Use gorilla mux route name as Prometheus path label

This commit is contained in:
Stefan Prodan
2018-08-21 15:19:21 +03:00
parent feac686e60
commit 979fd669df
2 changed files with 24 additions and 8 deletions

View File

@@ -10,6 +10,7 @@ import (
"strings"
"time"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus"
)
@@ -45,21 +46,36 @@ func NewPrometheusMiddleware() *PrometheusMiddleware {
}
}
func (i *PrometheusMiddleware) Handler(next http.Handler) http.Handler {
func (p *PrometheusMiddleware) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
begin := time.Now()
interceptor := &interceptor{ResponseWriter: w, statusCode: http.StatusOK}
path := urlToLabel(r.URL.Path)
path := p.getRouteName(r)
next.ServeHTTP(interceptor, r)
var (
status = strconv.Itoa(interceptor.statusCode)
took = time.Since(begin)
)
i.Histogram.WithLabelValues(r.Method, path, status).Observe(took.Seconds())
i.Counter.WithLabelValues(status).Inc()
p.Histogram.WithLabelValues(r.Method, path, status).Observe(took.Seconds())
p.Counter.WithLabelValues(status).Inc()
})
}
// converts gorilla mux routes from '/api/delay/{wait}' to 'api_delay_wait'
func (p *PrometheusMiddleware) getRouteName(r *http.Request) string {
if mux.CurrentRoute(r) != nil {
if name := mux.CurrentRoute(r).GetName(); len(name) > 0 {
return urlToLabel(name)
}
if path, err := mux.CurrentRoute(r).GetPathTemplate(); err == nil {
if len(path) > 0 {
return urlToLabel(path)
}
}
}
return urlToLabel(r.RequestURI)
}
var invalidChars = regexp.MustCompile(`[^a-zA-Z0-9]+`)
// converts a URL path to a string compatible with Prometheus label value.

View File

@@ -61,16 +61,16 @@ func (s *Server) registerHandlers() {
s.router.HandleFunc("/", s.infoHandler).Methods("GET")
s.router.HandleFunc("/version", s.versionHandler).Methods("GET")
s.router.HandleFunc("/echo", s.echoHandler).Methods("POST")
s.router.HandleFunc("/headers", s.echoHeadersHandler).Methods("GET")
s.router.HandleFunc("/delay/{wait:[0-9]+}", s.delayHandler).Methods("GET")
s.router.HandleFunc("/headers", s.echoHeadersHandler).Methods("GET", "POST")
s.router.HandleFunc("/delay/{wait:[0-9]+}", s.delayHandler).Methods("GET").Name("delay")
s.router.HandleFunc("/healthz", s.healthzHandler).Methods("GET")
s.router.HandleFunc("/readyz", s.readyzHandler).Methods("GET")
s.router.HandleFunc("/readyz/enable", s.enableReadyHandler).Methods("POST")
s.router.HandleFunc("/readyz/disable", s.disableReadyHandler).Methods("POST")
s.router.HandleFunc("/panic", s.panicHandler).Methods("GET")
s.router.HandleFunc("/status/{code:[0-9]+}", s.statusHandler).Methods("GET", "POST", "PUT")
s.router.HandleFunc("/status/{code:[0-9]+}", s.statusHandler).Methods("GET", "POST", "PUT").Name("status")
s.router.HandleFunc("/store", s.storeWriteHandler).Methods("POST")
s.router.HandleFunc("/store/{hash}", s.storeReadHandler).Methods("GET")
s.router.HandleFunc("/store/{hash}", s.storeReadHandler).Methods("GET").Name("store")
s.router.HandleFunc("/configs", s.configReadHandler).Methods("GET")
s.router.HandleFunc("/api/info", s.infoHandler).Methods("GET")
s.router.HandleFunc("/api/echo", s.echoHandler).Methods("POST")