Spring Boot version: 3.0.5
When calling an endpoint with a wrong method, or content-type, the URI tag when calling the metrics endpoint of the Actuator shows the corresponding URI as UNKNOWN.
Example with Prometheus exporter - localhost:8080/test with correct GET verb -> http_server_requests_seconds_count{error="none",exception="none",method="GET",outcome="SUCCESS",status="200",uri="/test",} 1.0 - localhost:8080/test with incorrect POST verb -> http_server_requests_seconds_count{error="none",exception="none",method="POST",outcome="CLIENT_ERROR",status="405",uri="UNKNOWN",} 4.0
Expected outcome Expected outcome would be to include the correct URI instead of UNKNOWN in the tag. I realize that we technically don't call the correct endpoint so the call "doesn't count", however I believe this doesn't line up with expectations.
Investigation
I already did some digging, in the AbstractHandlerMethodMapping
class, on line 437, we call handleMatch(bestMatch.mapping, lookupPath, request);
, which fills in the URI of the ServerRequestObservationContext
. The handleMatch()
method is never called of course in the case of a 405 or 415.
If wanted, I can spend some time to fix it.
Comment From: zhangzx1996
UNKNOWN often appears in the uri of/actuator/prometheus requests when using prometheus, how to fix it? thank you.
Comment From: zhangzx1996
Seems to be from ServerHttpObservationFilter#createOrFetchObservation method created in ServerRequestObservationContext object does not call setPathPattern method
Comment From: bclozel
By design, we cannot have tags in metrics with unbounded values. This means we cannot use the URI sent by the client as the uri tag for the metric recorded. The RequestMappingInfoHandlerMapping.PartialMatchHelper
only helps us to understand if there were partial matches and tries to respond accordingly, depending on: HTTP method mismatch, produce/consume conditions or parameters.
Since there is no match, we can only guess what likely happened, but we cannot know fur sure which handler was supposed to be called. Let's use the following example:
@GetMapping(path = "/t?st", produces = "application/xml")
public String getTest() {
//...
}
@PutMapping(path = "/te?t", produces = "application/json")
public String putTest() {
//...
}
@DeleteMapping("/**")
public String delete() {
//...
}
If a POST /test
request is sent without any "Accept" headers, which URI template are we supposed to use for metrics?
In light of that, I'm closing this issue as I don't think we can consistently have a uri tag for no-match cases.