diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java index 1c0f623da..df0795bba 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFilter.java @@ -41,6 +41,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; +import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; @@ -262,7 +263,7 @@ public final class TraceWebFilter implements WebFilter, Ordered { this.exchange.getResponse(), this.span); WrappedResponse response = new WrappedResponse( this.exchange.getResponse(), - this.exchange.getRequest().getMethodValue(), httpRoute); + this.exchange.getRequest().getMethodValue(), httpRoute, t); this.handler.handleSend(response, t, this.span); if (log.isDebugEnabled()) { log.debug("Handled send of " + this.span); @@ -376,10 +377,14 @@ public final class TraceWebFilter implements WebFilter, Ordered { final String httpRoute; - WrappedResponse(ServerHttpResponse resp, String method, String httpRoute) { + final Throwable throwable; + + WrappedResponse(ServerHttpResponse resp, String method, String httpRoute, + Throwable throwable) { this.delegate = resp; this.method = method; this.httpRoute = httpRoute; + this.throwable = throwable; } @Override @@ -399,6 +404,10 @@ public final class TraceWebFilter implements WebFilter, Ordered { @Override public int statusCode() { + if (this.throwable != null + && this.throwable instanceof ResponseStatusException) { + return ((ResponseStatusException) this.throwable).getStatus().value(); + } return delegate.getStatusCode() != null ? delegate.getStatusCode().value() : 0; } diff --git a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java index 89fad508a..803d113ec 100644 --- a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java @@ -82,6 +82,12 @@ public class TraceWebFluxTests { thenFunctionalSpanWasReportedWithTags(spans, response); spans.clear(); + // when + response = whenRequestIsSent(port, "/missing-endpoint"); + // then + thenSpanWith404StatusCodeWasReported(spans, response); + spans.clear(); + // when ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port); // then @@ -136,6 +142,15 @@ public class TraceWebFluxTests { value -> then(value).startsWith("TraceWebFluxTests$Config$$Lambda$")); } + private void thenSpanWith404StatusCodeWasReported(TestSpanHandler spans, + ClientResponse response) { + Awaitility.await() + .untilAsserted(() -> then(response.statusCode().value()).isEqualTo(404)); + then(spans).hasSize(1); + then(spans.get(0).tags()).hasEntrySatisfying("http.status_code", + value -> then(value).isEqualTo("404")); + } + private void thenNoSpanWasReported(TestSpanHandler spans, ClientResponse response, Controller2 controller2) { Awaitility.await().untilAsserted(() -> {