PMM-15228 Enrich AuthServer with performance metrics#5670
Conversation
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5670 +/- ##
==========================================
- Coverage 43.59% 43.39% -0.20%
==========================================
Files 415 433 +18
Lines 43134 35106 -8028
Branches 0 592 +592
==========================================
- Hits 18804 15236 -3568
+ Misses 22454 18322 -4132
+ Partials 1876 1548 -328
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
updated |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
managed/services/grafana/auth_server.go:588
extractOriginalRequestnow fails hard whencleanPathcan't unescape the original URI (e.g., invalid % escapes), which makesServeHTTPreturn 400. NGINXauth_requesttreats any non-401/403 response as 500, so malformed paths can turn into server errors. Consider falling back to the raw path (without query) instead of returning an error here.
cleanedOrigURI, err := cleanPath(origURI)
if err != nil {
return fmt.Errorf("failed to unescape path %q: %w", origURI, err)
}
managed/services/grafana/auth_server.go:399
- The
routelabel value is currently the full (cleaned) request path (req.URL.Path). Even without query parameters this can still be very high-cardinality (IDs, UIDs, etc.), which risks unbounded time-series growth and increased memory/CPU in Prometheus and in-process metric vectors. A bounded label (e.g., the matched rule prefix returned byresolveRule) would avoid this.
status := httpStatusForAuthError(authErr.code)
s.incAuthRequests(req.Method, req.URL.Path, status)
s.returnError(rw, status, m, l)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
managed/services/grafana/auth_server.go:374
- In the bad-request branch, if cleanPath(route) fails you fall back to using the raw (user-controlled) X-Original-Uri value as the "route" label. That allows an attacker to generate unbounded label cardinality (and in-process memory growth inside CounterVec) by sending many distinct invalid-escape paths. Consider using a bounded fallback label (e.g. "/invalid" or "") and/or capping route length when cleaning fails, rather than emitting the raw value.
route := req.Header.Get("X-Original-Uri")
if route == "" {
route = req.URL.Path
} else if i := strings.IndexByte(route, '?'); i >= 0 {
route = route[:i]
}
cleaned, cleanErr := cleanPath(route)
if cleanErr == nil {
route = cleaned
}
managed/services/grafana/auth_server.go:748
- New metrics behavior is added for cache hits/misses and Grafana backend request outcomes, but only the bad-request route labeling is covered by tests. Adding unit tests around getAuthUser/retrieveRole to assert cache hit/miss counters and Grafana status_code counters would help prevent regressions (e.g., ensuring miss is recorded on stale/absent cache and Grafana counters increment on success/clientError/unknown error).
if ok && time.Since(item.created) < cacheInvalidationInterval {
s.incCacheHit()
return &item.u, nil
}
s.incCacheMiss()
return s.retrieveRole(ctx, hash, authHeaders, l)
Ticket number: PMM-15228
Feature build: Percona-Lab/pmm-submodules#4484
This pull request adds detailed Prometheus metrics to the
AuthServercomponent in order to monitor authentication request flows, cache usage, and request durations. It also ensures that metrics are accurately labeled, especially in error scenarios, and improves code clarity around request path handling.Prometheus Metrics Integration:
authMetricsstruct toAuthServerthat defines and registers Prometheus counters and histograms for tracking authentication requests, cache hits/misses, Grafana backend requests, cache size, and operation durations. (managed/services/grafana/auth_server.go)prom.Collectorinterface forAuthServer, allowing it to be registered with Prometheus and report its metrics. (managed/services/grafana/auth_server.go)AuthServeras a Prometheus collector in the main application entrypoint. (managed/cmd/pmm-managed/main.go)Metrics Collection in Auth Flow:
managed/services/grafana/auth_server.go) [1] [2] [3]managed/services/grafana/auth_server.go)Testing and Path Handling Improvements:
managed/services/grafana/auth_server_test.go)managed/services/grafana/auth_server.go) [1] [2]These changes provide better observability into authentication operations and improve the maintainability and correctness of metrics reporting.