From b0327c2953c3c9bc2f8e53ef60de255c42df2eb5 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Fri, 8 Jul 2022 14:45:05 +0530 Subject: [PATCH] MM-45536: Track GraphQL queries in Grafana (#20609) https://mattermost.atlassian.net/browse/MM-45536 ```release-note NONE ``` --- api4/graphql.go | 2 ++ web/context.go | 15 +++++++++------ web/handlers.go | 9 ++++++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/api4/graphql.go b/api4/graphql.go index 19d4208227..4edbc31c27 100644 --- a/api4/graphql.go +++ b/api4/graphql.go @@ -101,6 +101,8 @@ func (api *API) graphQL(c *Context, w http.ResponseWriter, r *http.Request) { return } + c.GraphQLOperationName = params.OperationName + // Populate the context with required info. reqCtx := r.Context() reqCtx = context.WithValue(reqCtx, webCtx, c) diff --git a/web/context.go b/web/context.go index 292ba94619..fdfcb97428 100644 --- a/web/context.go +++ b/web/context.go @@ -19,12 +19,15 @@ import ( ) type Context struct { - App app.AppIface - AppContext *request.Context - Logger *mlog.Logger - Params *Params - Err *model.AppError - siteURLHeader string + App app.AppIface + AppContext *request.Context + Logger *mlog.Logger + Params *Params + Err *model.AppError + // This is used to track the graphQL query that's being executed, + // so that we can monitor the timings in Grafana. + GraphQLOperationName string + siteURLHeader string } // LogAuditRec logs an audit record using default LevelAPI. diff --git a/web/handlers.go b/web/handlers.go index 8602bf9d34..9a37fc4b35 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -382,7 +382,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path != model.APIURLSuffix+"/websocket" { elapsed := float64(time.Since(now)) / float64(time.Second) - c.App.Metrics().ObserveAPIEndpointDuration(h.HandlerName, r.Method, statusCode, elapsed) + var endpoint string + if strings.HasPrefix(r.URL.Path, model.APIURLSuffixV5) { + // It's a graphQL query, so use the operation name. + endpoint = c.GraphQLOperationName + } else { + endpoint = h.HandlerName + } + c.App.Metrics().ObserveAPIEndpointDuration(endpoint, r.Method, statusCode, elapsed) } } }