metrics: add operation name used in metrics/tracing for middlewares (#53949)

Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
Carl Bergquist 2022-08-25 10:11:27 +02:00 committed by GitHub
parent 8eac5706fd
commit ab59f3cb1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 3 deletions

View File

@ -525,7 +525,7 @@ func (hs *HTTPServer) applyRoutes() {
// then add view routes & api routes
hs.RouteRegister.Register(hs.web, hs.namedMiddlewares...)
// lastly not found route
hs.web.NotFound(middleware.ReqSignedIn, hs.NotFoundHandler)
hs.web.NotFound(middleware.ProvideRouteOperationName("notfound"), middleware.ReqSignedIn, hs.NotFoundHandler)
}
func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() {

View File

@ -38,3 +38,21 @@ func TestCanGetRouteNameFromContext(t *testing.T) {
assert.Equal(t, tc.expected, handler)
}
}
func TestOperationNameCanOnlyBeSetOnce(t *testing.T) {
req, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "https://grafana.com", nil)
// set the the initial operation name
req = addRouteNameToContext(req, "first")
// check that the operation name is set correctly
value, exists := routeOperationName(req)
assert.True(t, exists, "route name should exist")
assert.Equal(t, "first", value)
// check that it cannot be overwritten
req = addRouteNameToContext(req, "second")
value, exists = routeOperationName(req)
assert.True(t, exists, "route name should exist")
assert.Equal(t, "first", value)
}

View File

@ -27,11 +27,20 @@ var routeOperationNameKey = contextKey{}
// Implements routing.RegisterNamedMiddleware.
func ProvideRouteOperationName(name string) web.Handler {
return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
ctx := context.WithValue(c.Req.Context(), routeOperationNameKey, name)
c.Req = c.Req.WithContext(ctx)
c.Req = addRouteNameToContext(c.Req, name)
}
}
func addRouteNameToContext(req *http.Request, operationName string) *http.Request {
// don't set route name if it's set
if _, exists := routeOperationName(req); exists {
return req
}
ctx := context.WithValue(req.Context(), routeOperationNameKey, operationName)
return req.WithContext(ctx)
}
var unnamedHandlers = []struct {
pathPattern *regexp.Regexp
handler string