From e236eb74fa0d18374b77a6dbee578b3322113d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Fri, 20 Sep 2019 15:09:58 +0200 Subject: [PATCH] Add prometheous metrics for each api handler (#12254) --- api4/handlers.go | 5 +++++ einterfaces/metrics.go | 1 + web/handlers.go | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/api4/handlers.go b/api4/handlers.go index acdf1d03d5..41bf74f758 100644 --- a/api4/handlers.go +++ b/api4/handlers.go @@ -18,6 +18,7 @@ func (api *API) ApiHandler(h func(*Context, http.ResponseWriter, *http.Request)) handler := &web.Handler{ GetGlobalAppOptions: api.GetGlobalAppOptions, HandleFunc: h, + HandlerName: web.GetHandlerName(h), RequireSession: false, TrustRequester: false, RequireMfa: false, @@ -35,6 +36,7 @@ func (api *API) ApiSessionRequired(h func(*Context, http.ResponseWriter, *http.R handler := &web.Handler{ GetGlobalAppOptions: api.GetGlobalAppOptions, HandleFunc: h, + HandlerName: web.GetHandlerName(h), RequireSession: true, TrustRequester: false, RequireMfa: true, @@ -54,6 +56,7 @@ func (api *API) ApiSessionRequiredMfa(h func(*Context, http.ResponseWriter, *htt handler := &web.Handler{ GetGlobalAppOptions: api.GetGlobalAppOptions, HandleFunc: h, + HandlerName: web.GetHandlerName(h), RequireSession: true, TrustRequester: false, RequireMfa: false, @@ -73,6 +76,7 @@ func (api *API) ApiHandlerTrustRequester(h func(*Context, http.ResponseWriter, * handler := &web.Handler{ GetGlobalAppOptions: api.GetGlobalAppOptions, HandleFunc: h, + HandlerName: web.GetHandlerName(h), RequireSession: false, TrustRequester: true, RequireMfa: false, @@ -91,6 +95,7 @@ func (api *API) ApiSessionRequiredTrustRequester(h func(*Context, http.ResponseW handler := &web.Handler{ GetGlobalAppOptions: api.GetGlobalAppOptions, HandleFunc: h, + HandlerName: web.GetHandlerName(h), RequireSession: true, TrustRequester: true, RequireMfa: true, diff --git a/einterfaces/metrics.go b/einterfaces/metrics.go index b604b895be..b6319225bc 100644 --- a/einterfaces/metrics.go +++ b/einterfaces/metrics.go @@ -44,4 +44,5 @@ type MetricsInterface interface { IncrementPostsSearchCounter() ObservePostsSearchDuration(elapsed float64) ObserveStoreMethodDuration(method string, success string, elapsed float64) + ObserveApiEndpointDuration(endpoint string, elapsed float64) } diff --git a/web/handlers.go b/web/handlers.go index 9269a04e93..a666501f6d 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -6,6 +6,9 @@ package web import ( "fmt" "net/http" + "reflect" + "runtime" + "strings" "time" "github.com/NYTimes/gziphandler" @@ -16,10 +19,20 @@ import ( "github.com/mattermost/mattermost-server/utils" ) +func GetHandlerName(h func(*Context, http.ResponseWriter, *http.Request)) string { + handlerName := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name() + pos := strings.LastIndex(handlerName, ".") + if pos != -1 && len(handlerName) > pos { + handlerName = handlerName[pos+1:] + } + return handlerName +} + func (w *Web) NewHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler { return &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: false, TrustRequester: false, RequireMfa: false, @@ -35,6 +48,7 @@ func (w *Web) NewStaticHandler(h func(*Context, http.ResponseWriter, *http.Reque return &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: false, TrustRequester: false, RequireMfa: false, @@ -47,6 +61,7 @@ func (w *Web) NewStaticHandler(h func(*Context, http.ResponseWriter, *http.Reque type Handler struct { GetGlobalAppOptions app.AppOptionCreator HandleFunc func(*Context, http.ResponseWriter, *http.Request) + HandlerName string RequireSession bool TrustRequester bool RequireMfa bool @@ -192,6 +207,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path != model.API_URL_SUFFIX+"/websocket" { elapsed := float64(time.Since(now)) / float64(time.Second) c.App.Metrics.ObserveHttpRequestDuration(elapsed) + c.App.Metrics.ObserveApiEndpointDuration(h.HandlerName, elapsed) } } } @@ -249,6 +265,7 @@ func (w *Web) ApiHandler(h func(*Context, http.ResponseWriter, *http.Request)) h handler := &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: false, TrustRequester: false, RequireMfa: false, @@ -267,6 +284,7 @@ func (w *Web) ApiHandlerTrustRequester(h func(*Context, http.ResponseWriter, *ht handler := &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: false, TrustRequester: true, RequireMfa: false, @@ -284,6 +302,7 @@ func (w *Web) ApiSessionRequired(h func(*Context, http.ResponseWriter, *http.Req handler := &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: true, TrustRequester: false, RequireMfa: true, @@ -302,6 +321,7 @@ func (w *Web) apiHandlerTrustRequester(h func(*Context, http.ResponseWriter, *ht handler := &Handler{ GetGlobalAppOptions: w.GetGlobalAppOptions, HandleFunc: h, + HandlerName: GetHandlerName(h), RequireSession: false, TrustRequester: true, RequireMfa: false,