diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java index 5266508b325c..70f5207a8ce6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTags.java @@ -109,7 +109,8 @@ public static Tag uri(ServerWebExchange exchange) { */ public static Tag exception(Throwable exception) { if (exception != null) { - return Tag.of("exception", exception.getClass().getSimpleName()); + String simpleName = exception.getClass().getSimpleName(); + return Tag.of("exception", simpleName.isEmpty() ? exception.getClass().getName() : simpleName); } return EXCEPTION_NONE; } 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 f469b6ba72fd..3cb0e05f53f2 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 @@ -134,9 +134,11 @@ private static String getPathInfo(HttpServletRequest request) { * @return the exception tag derived from the exception */ public static Tag exception(Throwable exception) { - return (exception != null - ? Tag.of("exception", exception.getClass().getSimpleName()) - : EXCEPTION_NONE); + if (exception != null) { + String simpleName = exception.getClass().getSimpleName(); + return Tag.of("exception", simpleName.isEmpty() ? exception.getClass().getName() : simpleName); + } + return EXCEPTION_NONE; } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/MetricsWebFilterTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/MetricsWebFilterTests.java index 45d9acbe3e6f..6e2dbb9e42ad 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/MetricsWebFilterTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/MetricsWebFilterTests.java @@ -77,6 +77,26 @@ public void filterAddsTagsToRegistryForExceptions() { }).block(); assertMetricsContainsTag("uri", "/projects/{project}"); assertMetricsContainsTag("status", "500"); + assertMetricsContainsTag("exception", "IllegalStateException"); + } + + @Test + public void filterAddsNonEmptyTagsToRegistryForAnonymousExceptions() { + final Exception anonymous = new Exception("test error") {}; + + MockServerWebExchange exchange = createExchange("/projects/spring-boot", + "/projects/{project}"); + this.webFilter + .filter(exchange, + (serverWebExchange) -> Mono + .error(anonymous)) + .onErrorResume((t) -> { + exchange.getResponse().setStatusCodeValue(500); + return exchange.getResponse().setComplete(); + }).block(); + assertMetricsContainsTag("uri", "/projects/{project}"); + assertMetricsContainsTag("status", "500"); + assertMetricsContainsTag("exception", anonymous.getClass().getName()); } @Test diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java index db6a9038dd67..2fe56687540d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java @@ -188,6 +188,18 @@ public void unhandledError() { .tags("exception", "RuntimeException").timer().count()).isEqualTo(1L); } + @Test + public void anonymousError() throws Exception { + try { + mvc.perform(get("/api/c1/anonymousError/10")); + } catch(Throwable ignore) { + } + + assertThat(this.registry.get("http.server.requests").tag("uri", "/api/c1/anonymousError/{id}").timer().getId() + .getTag("exception")) + .endsWith("$1"); + } + @Test public void asyncCallableRequest() throws Exception { AtomicReference result = new AtomicReference<>(); @@ -440,6 +452,12 @@ public String alwaysThrowsException(@PathVariable Long id) { throw new IllegalStateException("Boom on " + id + "!"); } + @Timed + @GetMapping("/anonymousError/{id}") + public String alwaysThrowsAnonymousException(@PathVariable Long id) throws Exception { + throw new Exception("this exception won't have a simple class name") {}; + } + @Timed @GetMapping("/unhandledError/{id}") public String alwaysThrowsUnhandledException(@PathVariable Long id) {