diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java index 7bc202ea46..0dd146ad57 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcTags.java @@ -26,6 +26,7 @@ import io.micrometer.core.instrument.Tag; import org.springframework.http.HttpStatus; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPattern; /** * Factory methods for {@link Tag Tags} associated with a request-response exchange that @@ -39,6 +40,8 @@ import org.springframework.web.servlet.HandlerMapping; */ public final class WebMvcTags { + private static final String DATA_REST_PATH_PATTERN_ATTRIBUTE = "org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH"; + private static final Tag URI_NOT_FOUND = Tag.of("uri", "NOT_FOUND"); private static final Tag URI_REDIRECTION = Tag.of("uri", "REDIRECTION"); @@ -138,6 +141,11 @@ public final class WebMvcTags { } private static String getMatchingPattern(HttpServletRequest request) { + PathPattern dataRestPathPattern = (PathPattern) request + .getAttribute(DATA_REST_PATH_PATTERN_ATTRIBUTE); + if (dataRestPathPattern != null) { + return dataRestPathPattern.getPatternString(); + } return (String) request .getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java index 043b12268b..5f2f4a52c1 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcTagsTests.java @@ -23,6 +23,7 @@ import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTags; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; import static org.assertj.core.api.Assertions.assertThat; @@ -39,6 +40,17 @@ public class WebMvcTagsTests { private final MockHttpServletResponse response = new MockHttpServletResponse(); + @Test + public void uriTagIsDataRestsEffectiveRepositoryLookupPathWhenAvailable() { + this.request.setAttribute( + "org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH", + new PathPatternParser().parse("/api/cities")); + this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, + "/api/{repository}"); + Tag tag = WebMvcTags.uri(this.request, this.response); + assertThat(tag.getValue()).isEqualTo("/api/cities"); + } + @Test public void uriTagValueIsBestMatchingPatternWhenAvailable() { this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE,