prometheus: middleware to record 5xx errors

Create a custom middleware function
to measure 5xx requests for all composer
& worker routes and not just the `/composer`
endpoint. The result is a prometheus metric
that contains info on the request status code,
path & method.

A helper function has been added to clean the
dynamic parameters in the path routes to reduce
metric cardinality
This commit is contained in:
Gianluca Zuccarelli 2022-11-21 17:04:39 +00:00 committed by Ondřej Budai
parent 33e53398a6
commit 8756ea717d
2 changed files with 49 additions and 0 deletions

View file

@ -0,0 +1,15 @@
package prometheus
import (
"regexp"
"strings"
)
func pathLabel(path string) string {
r := regexp.MustCompile(":(.*)")
segments := strings.Split(path, "/")
for i, segment := range segments {
segments[i] = r.ReplaceAllString(segment, "-")
}
return strings.Join(segments, "/")
}

View file

@ -1,6 +1,8 @@
package prometheus
import (
"errors"
"strconv"
"strings"
"github.com/labstack/echo/v4"
@ -18,3 +20,35 @@ func MetricsMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return next(ctx)
}
}
func StatusMiddleware(subsystem string) func(next echo.HandlerFunc) echo.HandlerFunc {
counter := StatusRequestsCounter(subsystem)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(ctx echo.Context) error {
// call the next handler to see if
// an error occurred, see:
// - https://github.com/labstack/echo/issues/1837#issuecomment-816399630
// - https://github.com/labstack/echo/discussions/1820#discussioncomment-529428
err := next(ctx)
path := pathLabel(ctx.Path())
method := ctx.Request().Method
status := ctx.Response().Status
httpErr := new(echo.HTTPError)
if errors.As(err, &httpErr) {
status = httpErr.Code
}
counter.WithLabelValues(
method,
path,
strconv.Itoa(status),
subsystem,
).Inc()
return err
}
}
}