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 782579279a..3325c19509 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 @@ -45,8 +45,12 @@ public final class WebFluxTags { private static final Tag OUTCOME_UNKNOWN = Tag.of("outcome", "UNKNOWN"); + private static final Tag OUTCOME_INFORMATIONAL = Tag.of("outcome", "INFORMATIONAL"); + private static final Tag OUTCOME_SUCCESS = Tag.of("outcome", "SUCCESS"); + private static final Tag OUTCOME_REDIRECTION = Tag.of("outcome", "REDIRECTION"); + private static final Tag OUTCOME_CLIENT_ERROR = Tag.of("outcome", "CLIENT_ERROR"); private static final Tag OUTCOME_SERVER_ERROR = Tag.of("outcome", "SERVER_ERROR"); @@ -125,25 +129,26 @@ public final class WebFluxTags { * Creates a {@code outcome} tag based on the response status of the given * {@code exchange}. * @param exchange the exchange - * @return the "outcome" tag derived from the response status + * @return the outcome tag derived from the response status */ public static Tag outcome(ServerWebExchange exchange) { - if (exchange != null && exchange.getResponse().getStatusCode() != null) { - HttpStatus status = exchange.getResponse().getStatusCode(); - if (status.is1xxInformational() || status.is2xxSuccessful() - || status.is3xxRedirection()) { + HttpStatus status = exchange.getResponse().getStatusCode(); + if (status != null) { + if (status.is1xxInformational()) { + return OUTCOME_INFORMATIONAL; + } + if (status.is2xxSuccessful()) { return OUTCOME_SUCCESS; } - else if (status.is4xxClientError()) { + if (status.is3xxRedirection()) { + return OUTCOME_REDIRECTION; + } + if (status.is4xxClientError()) { return OUTCOME_CLIENT_ERROR; } - else { - return OUTCOME_SERVER_ERROR; - } - } - else { - return OUTCOME_UNKNOWN; + return OUTCOME_SERVER_ERROR; } + return OUTCOME_UNKNOWN; } } 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 a7ba72a427..bf587d4c58 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 @@ -53,8 +53,12 @@ public final class WebMvcTags { private static final Tag OUTCOME_UNKNOWN = Tag.of("outcome", "UNKNOWN"); + private static final Tag OUTCOME_INFORMATIONAL = Tag.of("outcome", "INFORMATIONAL"); + private static final Tag OUTCOME_SUCCESS = Tag.of("outcome", "SUCCESS"); + private static final Tag OUTCOME_REDIRECTION = Tag.of("outcome", "REDIRECTION"); + private static final Tag OUTCOME_CLIENT_ERROR = Tag.of("outcome", "CLIENT_ERROR"); private static final Tag OUTCOME_SERVER_ERROR = Tag.of("outcome", "SERVER_ERROR"); @@ -166,19 +170,21 @@ public final class WebMvcTags { public static Tag outcome(HttpServletResponse response) { if (response != null) { int status = response.getStatus(); - if (status < 400) { + if (status < 200) { + return OUTCOME_INFORMATIONAL; + } + if (status < 300) { return OUTCOME_SUCCESS; } + if (status < 400) { + return OUTCOME_REDIRECTION; + } else if (status < 500) { return OUTCOME_CLIENT_ERROR; } - else { - return OUTCOME_SERVER_ERROR; - } - } - else { - return OUTCOME_UNKNOWN; + return OUTCOME_SERVER_ERROR; } + return OUTCOME_UNKNOWN; } } 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 df3e15d5ab..043b12268b 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 @@ -99,21 +99,35 @@ public class WebMvcTagsTests { } @Test - public void outcomeTagIsSuccessWhenResponseIs2XX() { + public void outcomeTagIsInformationalWhenResponseIs1xx() { + this.response.setStatus(100); + Tag tag = WebMvcTags.outcome(this.response); + assertThat(tag.getValue()).isEqualTo("INFORMATIONAL"); + } + + @Test + public void outcomeTagIsSuccessWhenResponseIs2xx() { this.response.setStatus(200); Tag tag = WebMvcTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SUCCESS"); } @Test - public void outcomeTagIsClientErrorWhenResponseIs4XX() { + public void outcomeTagIsRedirectionWhenResponseIs3xx() { + this.response.setStatus(301); + Tag tag = WebMvcTags.outcome(this.response); + assertThat(tag.getValue()).isEqualTo("REDIRECTION"); + } + + @Test + public void outcomeTagIsClientErrorWhenResponseIs4xx() { this.response.setStatus(400); Tag tag = WebMvcTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test - public void outcomeTagIsServerErrorWhenResponseIs5XX() { + public void outcomeTagIsServerErrorWhenResponseIs5xx() { this.response.setStatus(500); Tag tag = WebMvcTags.outcome(this.response); assertThat(tag.getValue()).isEqualTo("SERVER_ERROR"); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java index b342ffaf55..83d042239c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/server/WebFluxTagsTests.java @@ -89,12 +89,6 @@ public class WebFluxTagsTests { assertThat(tag.getValue()).isEqualTo("CUSTOM"); } - @Test - public void outcomeTagIsUnknownWhenResponseIsNull() { - Tag tag = WebFluxTags.outcome(null); - assertThat(tag.getValue()).isEqualTo("UNKNOWN"); - } - @Test public void outcomeTagIsUnknownWhenResponseStatusIsNull() { this.exchange.getResponse().setStatusCode(null); @@ -103,21 +97,35 @@ public class WebFluxTagsTests { } @Test - public void outcomeTagIsSuccessWhenResponseIs2XX() { + public void outcomeTagIsInformationalWhenResponseIs1xx() { + this.exchange.getResponse().setStatusCode(HttpStatus.CONTINUE); + Tag tag = WebFluxTags.outcome(this.exchange); + assertThat(tag.getValue()).isEqualTo("INFORMATIONAL"); + } + + @Test + public void outcomeTagIsSuccessWhenResponseIs2xx() { this.exchange.getResponse().setStatusCode(HttpStatus.OK); Tag tag = WebFluxTags.outcome(this.exchange); assertThat(tag.getValue()).isEqualTo("SUCCESS"); } @Test - public void outcomeTagIsClientErrorWhenResponseIs4XX() { + public void outcomeTagIsRedirectionWhenResponseIs3xx() { + this.exchange.getResponse().setStatusCode(HttpStatus.MOVED_PERMANENTLY); + Tag tag = WebFluxTags.outcome(this.exchange); + assertThat(tag.getValue()).isEqualTo("REDIRECTION"); + } + + @Test + public void outcomeTagIsClientErrorWhenResponseIs4xx() { this.exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); Tag tag = WebFluxTags.outcome(this.exchange); assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR"); } @Test - public void outcomeTagIsServerErrorWhenResponseIs5XX() { + public void outcomeTagIsServerErrorWhenResponseIs5xx() { this.exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY); Tag tag = WebFluxTags.outcome(this.exchange); assertThat(tag.getValue()).isEqualTo("SERVER_ERROR"); diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 7effaadbe6..3671d5e8ea 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -1723,12 +1723,28 @@ customized by setting the `management.metrics.web.server.requests-metric-name` p By default, Spring MVC-related metrics are tagged with the following information: -* `method`, the request's method (for example, `GET` or `POST`). -* `uri`, the request's URI template prior to variable substitution, if possible (for -example, `/api/person/{id}`). -* `status`, the response's HTTP status code (for example, `200` or `500`). -* `exception`, the simple class name of any exception that was thrown while handling the -request. +|=== +|Tag |Description + +|`exception` +|Simple class name of any exception that was thrown while handling the request. + +|`method` +|Request's method (for example, `GET` or `POST`) + +|`outcome` +|Request's outcome based on the status code of the response. 1xx is +`INFORMATIONAL`, 2xx is `SUCCESS`, 3xx is `REDIRECTION`, 4xx `CLIENT_ERROR`, and 5xx is +`SERVER_ERROR` + +|`status` +|Response's HTTP status code (for example, `200` or `500`) + +|`uri` +|Request's URI template prior to variable substitution, if possible (for example, +`/api/person/{id}`) + +|=== To customize the tags, provide a `@Bean` that implements `WebMvcTagsProvider`. @@ -1744,12 +1760,28 @@ the name by setting the `management.metrics.web.server.requests-metric-name` pro By default, WebFlux-related metrics are tagged with the following information: -* `method`, the request's method (for example, `GET` or `POST`). -* `uri`, the request's URI template prior to variable substitution, if possible (for -example, `/api/person/{id}`). -* `status`, the response's HTTP status code (for example, `200` or `500`). -* `exception`, the simple class name of any exception that was thrown while handling the -request. +|=== +|Tag |Description + +|`exception` +|Simple class name of any exception that was thrown while handling the request. + +|`method` +|Request's method (for example, `GET` or `POST`) + +|`outcome` +|Request's outcome based on the status code of the response. 1xx is +`INFORMATIONAL`, 2xx is `SUCCESS`, 3xx is `REDIRECTION`, 4xx `CLIENT_ERROR`, and 5xx is +`SERVER_ERROR` + +|`status` +|Response's HTTP status code (for example, `200` or `500`) + +|`uri` +|Request's URI template prior to variable substitution, if possible (for example, +`/api/person/{id}`) + +|=== To customize the tags, provide a `@Bean` that implements `WebFluxTagsProvider`.