mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-21 06:20:31 +00:00
If we don't get a path name from the router, make one up from the url. (#1570)
* If we don't get a path name from the router, make one up from the url. * Think about route naming a little more and add a comment to show it.
This commit is contained in:
@@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -39,14 +40,45 @@ func (i Instrument) Wrap(next http.Handler) http.Handler {
|
||||
})
|
||||
}
|
||||
|
||||
// Return a name identifier for ths request. There are three options:
|
||||
// 1. The request matches a gorilla mux route, with a name. Use that.
|
||||
// 2. The request matches an unamed gorilla mux router. Munge the path
|
||||
// template such that templates like '/api/{org}/foo' come out as
|
||||
// 'api_org_foo'.
|
||||
// 3. The request doesn't match a mux route. Munge the Path in the same
|
||||
// manner as (2).
|
||||
// We do all this as we do not wish to emit high cardinality labels to
|
||||
// prometheus.
|
||||
func (i Instrument) getRouteName(r *http.Request) string {
|
||||
var routeMatch mux.RouteMatch
|
||||
if !i.RouteMatcher.Match(r, &routeMatch) {
|
||||
return "unmatched_path"
|
||||
if i.RouteMatcher.Match(r, &routeMatch) {
|
||||
if name := routeMatch.Route.GetName(); name != "" {
|
||||
return name
|
||||
}
|
||||
if tmpl, err := routeMatch.Route.GetPathTemplate(); err != nil {
|
||||
return MakeLabelValue(tmpl)
|
||||
}
|
||||
}
|
||||
name := routeMatch.Route.GetName()
|
||||
if name == "" {
|
||||
return "unnamed_path"
|
||||
}
|
||||
return name
|
||||
return MakeLabelValue(r.URL.Path)
|
||||
}
|
||||
|
||||
var invalidChars = regexp.MustCompile(`[^a-zA-Z0-9]+`)
|
||||
|
||||
// MakeLabelValue converts a Gorilla mux path to a string suitable for use in
|
||||
// a Prometheus label value.
|
||||
func MakeLabelValue(path string) string {
|
||||
// Convert non-alnums to underscores.
|
||||
result := invalidChars.ReplaceAllString(path, "_")
|
||||
|
||||
// Trim leading and trailing underscores.
|
||||
result = strings.Trim(result, "_")
|
||||
|
||||
// Make it all lowercase
|
||||
result = strings.ToLower(result)
|
||||
|
||||
// Special case.
|
||||
if result == "" {
|
||||
result = "root"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
30
common/middleware/instrument_test.go
Normal file
30
common/middleware/instrument_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package middleware_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/weaveworks/scope/common/middleware"
|
||||
)
|
||||
|
||||
func TestMakeLabelValue(t *testing.T) {
|
||||
for input, want := range map[string]string{
|
||||
"/": "root", // special case
|
||||
"//": "root", // unintended consequence of special case
|
||||
"a": "a",
|
||||
"/foo": "foo",
|
||||
"foo/": "foo",
|
||||
"/foo/": "foo",
|
||||
"/foo/bar": "foo_bar",
|
||||
"foo/bar/": "foo_bar",
|
||||
"/foo/bar/": "foo_bar",
|
||||
"/foo/{orgName}/Bar": "foo_orgname_bar",
|
||||
"/foo/{org_name}/Bar": "foo_org_name_bar",
|
||||
"/foo/{org__name}/Bar": "foo_org_name_bar",
|
||||
"/foo/{org___name}/_Bar": "foo_org_name_bar",
|
||||
"/foo.bar/baz.qux/": "foo_bar_baz_qux",
|
||||
} {
|
||||
if have := middleware.MakeLabelValue(input); want != have {
|
||||
t.Errorf("%q: want %q, have %q", input, want, have)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter
|
||||
app.RegisterPipeRoutes(router, pipeRouter)
|
||||
app.RegisterTopologyRoutes(router, collector)
|
||||
|
||||
router.PathPrefix("/").Handler(http.FileServer(FS(false)))
|
||||
router.PathPrefix("/").Name("static").Handler(http.FileServer(FS(false)))
|
||||
|
||||
instrument := middleware.Instrument{
|
||||
RouteMatcher: router,
|
||||
|
||||
Reference in New Issue
Block a user