Last active
February 4, 2022 09:51
-
-
Save MrDOS/ebdc448a795643b447750b213add38d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package config | |
import ( | |
"net/http" | |
"regexp" | |
"strings" | |
) | |
// idPatterns describes patterns of IDs in URLs. These patterns are matched | |
// against an entire URL. These patterns are used as given without any | |
// additional prefix or suffix, so to match against only one element of a path | |
// (e.g., only “bar” in “https://foo/bar/baz”), the patterns must include its | |
// own checks for path separators and the end of the URL. | |
var idPatterns = []struct { | |
pattern *regexp.Regexp | |
placeholder []byte | |
}{ | |
// Strictly numeric IDs (e.g., “/123”). | |
{ | |
regexp.MustCompile(`/\d+(/|$)`), | |
[]byte("/id$1"), | |
}, | |
// UUIDs (e.g., “00000000-0000-0000-0000-000000000000”). | |
{ | |
regexp.MustCompile(`/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}(/|$)`), | |
[]byte("/uuid$1"), | |
}, | |
} | |
// IDReplacer attempts to generate the resource name for an HTTP request by | |
// replacing portions which look like IDs with generic placeholders. Because we | |
// don't have access to the actual route pattern, we'll synthesize it by | |
// replacing anything in the URL which looks like a numeric ID or a UUID with a | |
// placeholder token (“id” or “uuid”, respectively). E.g., a GET request for: | |
// | |
// /api/foo/f9849b8d-455b-41fc-bec5-a45bc822023d/bar/42 | |
// | |
// will be transformed into: | |
// | |
// GET /api/foo/uuid/bar/id | |
// | |
// This may differ from the actual route definition; for example: | |
// | |
// /api/foo/:fooID/bar/:barID | |
// | |
// ...but it's close enough for tracing. | |
func IDReplacer(req *http.Request) string { | |
resource := req.URL.Path | |
for _, idPattern := range idPatterns { | |
resource = string(idPattern.pattern.ReplaceAll( | |
[]byte(resource), | |
idPattern.placeholder)) | |
} | |
// Route normalization: remove any trailing slashes so traces for | |
// extension-less routes are combined regardless of whether the request had | |
// a trailing slash (e.g., “/foo vs. “/foo/”). | |
if resource != "/" { | |
resource = strings.TrimRight(resource, "/") | |
} | |
return req.Method + " " + resource | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment