Search code examples
springspring-bootprometheusmicrometerspring-micrometer

Resolving POST /** request URL to full request URL using micrometer


With the micro-service architecture I have written a generic POST request handler which is consumed by all the micro-services. The post mapping in spring look like this:

@RestController
@RequestMapping(value = "/v1/", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
public class V1Controller {
    @PostMapping(path = "/**")
    public @ResponseBody Json post () {}
}

Now while I am consuming the metrics for this endpoint using micrometer I am only getting /v1/ as the endpoint in the metrics while I am sending the full URL like /v1/demo/foo from the calling service. I tried lot of the combination but it is not working. I have also added the WebMvcTagsProvider where I am listing to request and resolving the POST api calls.

@Bean
@SuppressWarnings("unchecked")
public WebMvcTagsProvider webMvcTagsProvider(ObjectMapper objectMapper) {
    return new DefaultWebMvcTagsProvider() {
        public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) {
            if ("POST".equals(request.getMethod())) {
                Tag uriTag = Tag.of("uri", String.valueOf(request.getRequestURI()));

                return Tags.of(WebMvcTags.method(request), uriTag, WebMvcTags.exception(exception), WebMvcTags.status(response));
            }

            return Tags.of(WebMvcTags.method(request), WebMvcTags.uri(request, response), WebMvcTags.exception(exception), WebMvcTags.status(response));
        }
    };
}

Still it is resolving to /v1/ URL in the metrics. I tried googling alot but didn't find any solution. Thanks in advance.


Solution

  • The build in Spring Boot RequestMapping based metrics match on the annotations and add those as tags.

    This is to avoid a tag explosion. Imagine a @RequestMapping for a path like user/{userId}, you would want to group all those calls together (user/1, user/2, user/3).

    You'll want to create your own Timer in your post method that set that url tags, etc there.

    If you decide to reuse the same metric name as the built in Spring Boot metric, you'll want to disable that one as well, so you don't double count those requests.