Add outcome tag to MVC and WebFlux HTTP request metrics
See gh-14486
This commit is contained in:
committed by
Andy Wilkinson
parent
6da483f970
commit
9e9dd40959
@@ -35,7 +35,8 @@ public class DefaultWebFluxTagsProvider implements WebFluxTagsProvider {
|
||||
public Iterable<Tag> httpRequestTags(ServerWebExchange exchange,
|
||||
Throwable exception) {
|
||||
return Arrays.asList(WebFluxTags.method(exchange), WebFluxTags.uri(exchange),
|
||||
WebFluxTags.exception(exception), WebFluxTags.status(exchange));
|
||||
WebFluxTags.exception(exception), WebFluxTags.status(exchange),
|
||||
WebFluxTags.outcome(exchange));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.web.util.pattern.PathPattern;
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @author Michael McFadyen
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public final class WebFluxTags {
|
||||
@@ -42,6 +43,14 @@ public final class WebFluxTags {
|
||||
|
||||
private static final Tag EXCEPTION_NONE = Tag.of("exception", "None");
|
||||
|
||||
private static final Tag OUTCOME_UNKNOWN = Tag.of("outcome", "UNKNOWN");
|
||||
|
||||
private static final Tag OUTCOME_SUCCESS = Tag.of("outcome", "SUCCESS");
|
||||
|
||||
private static final Tag OUTCOME_CLIENT_ERROR = Tag.of("outcome", "CLIENT_ERROR");
|
||||
|
||||
private static final Tag OUTCOME_SERVER_ERROR = Tag.of("outcome", "SERVER_ERROR");
|
||||
|
||||
private WebFluxTags() {
|
||||
}
|
||||
|
||||
@@ -112,4 +121,29 @@ public final class WebFluxTags {
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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()) {
|
||||
return OUTCOME_SUCCESS;
|
||||
}
|
||||
else if (status.is4xxClientError()) {
|
||||
return OUTCOME_CLIENT_ERROR;
|
||||
}
|
||||
else {
|
||||
return OUTCOME_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return OUTCOME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ public class DefaultWebMvcTagsProvider implements WebMvcTagsProvider {
|
||||
public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler, Throwable exception) {
|
||||
return Tags.of(WebMvcTags.method(request), WebMvcTags.uri(request, response),
|
||||
WebMvcTags.exception(exception), WebMvcTags.status(response));
|
||||
WebMvcTags.exception(exception), WebMvcTags.status(response),
|
||||
WebMvcTags.outcome(response));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.web.servlet.HandlerMapping;
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public final class WebMvcTags {
|
||||
@@ -50,6 +51,14 @@ public final class WebMvcTags {
|
||||
|
||||
private static final Tag STATUS_UNKNOWN = Tag.of("status", "UNKNOWN");
|
||||
|
||||
private static final Tag OUTCOME_UNKNOWN = Tag.of("outcome", "UNKNOWN");
|
||||
|
||||
private static final Tag OUTCOME_SUCCESS = Tag.of("outcome", "SUCCESS");
|
||||
|
||||
private static final Tag OUTCOME_CLIENT_ERROR = Tag.of("outcome", "CLIENT_ERROR");
|
||||
|
||||
private static final Tag OUTCOME_SERVER_ERROR = Tag.of("outcome", "SERVER_ERROR");
|
||||
|
||||
private static final Tag METHOD_UNKNOWN = Tag.of("method", "UNKNOWN");
|
||||
|
||||
private static final Pattern TRAILING_SLASH_PATTERN = Pattern.compile("/$");
|
||||
@@ -149,4 +158,27 @@ public final class WebMvcTags {
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code outcome} tag based on the status of the given {@code response}.
|
||||
* @param response the HTTP response
|
||||
* @return the outcome tag derived from the status of the response
|
||||
*/
|
||||
public static Tag outcome(HttpServletResponse response) {
|
||||
if (response != null) {
|
||||
int status = response.getStatus();
|
||||
if (status < 400) {
|
||||
return OUTCOME_SUCCESS;
|
||||
}
|
||||
else if (status < 500) {
|
||||
return OUTCOME_CLIENT_ERROR;
|
||||
}
|
||||
else {
|
||||
return OUTCOME_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return OUTCOME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
*/
|
||||
public class WebMvcTagsTests {
|
||||
|
||||
@@ -91,4 +92,31 @@ public class WebMvcTagsTests {
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeTagIsUnknownWhenResponseIsNull() {
|
||||
Tag tag = WebMvcTags.outcome(null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeTagIsSuccessWhenResponseIs2XX() {
|
||||
this.response.setStatus(200);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeTagIsClientErrorWhenResponseIs4XX() {
|
||||
this.response.setStatus(400);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeTagIsServerErrorWhenResponseIs5XX() {
|
||||
this.response.setStatus(500);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.mock;
|
||||
* Tests for {@link WebFluxTags}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
*/
|
||||
public class WebFluxTagsTests {
|
||||
|
||||
@@ -88,4 +89,38 @@ 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);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@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() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outcomeTagIsServerErrorWhenResponseIs5XX() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user