Browse Source

Attaches error to Observation

without this change when there is no response and the observation closing web exception handler stops the observation we've forgotten to attach an error to it
with this change we're attaching the error
pull/2743/head
Marcin Grzejszczak 2 years ago
parent
commit
2682c3b3d4
  1. 3
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/DefaultGatewayObservationConvention.java
  2. 1
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayContext.java
  3. 1
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/ObservationClosingWebExceptionHandler.java
  4. 5
      spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java
  5. 4
      spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservationClosingWebExceptionHandlerTests.java
  6. 15
      spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java

3
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/DefaultGatewayObservationConvention.java

@ -50,7 +50,8 @@ public class DefaultGatewayObservationConvention implements GatewayObservationCo @@ -50,7 +50,8 @@ public class DefaultGatewayObservationConvention implements GatewayObservationCo
return keyValues;
}
Route route = context.getServerWebExchange().getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
keyValues = keyValues.and(ROUTE_URI.withValue(route.getUri().toString()),
keyValues = keyValues
.and(ROUTE_URI.withValue(route.getUri().toString()),
METHOD.withValue(context.getRequest().getMethod().name()))
.and(ROUTE_ID.withValue(route.getId()));
ServerHttpResponse response = context.getResponse();

1
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/GatewayContext.java

@ -53,4 +53,5 @@ public class GatewayContext extends RequestReplySenderContext<HttpHeaders, Serve @@ -53,4 +53,5 @@ public class GatewayContext extends RequestReplySenderContext<HttpHeaders, Serve
public ServerWebExchange getServerWebExchange() {
return serverWebExchange;
}
}

1
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/headers/observation/ObservationClosingWebExceptionHandler.java

@ -41,6 +41,7 @@ public class ObservationClosingWebExceptionHandler implements WebExceptionHandle @@ -41,6 +41,7 @@ public class ObservationClosingWebExceptionHandler implements WebExceptionHandle
Observation observation = exchange.getAttribute(ObservedRequestHttpHeadersFilter.CHILD_OBSERVATION);
if (observation != null) {
log.debug(() -> "Observation was not previously stopped, will stop it.");
observation.error(ex);
observation.stop();
}
}

5
spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/B3BraveObservedHttpHeadersFilterTests.java

@ -104,9 +104,8 @@ class B3BraveObservedHttpHeadersFilterTests { @@ -104,9 +104,8 @@ class B3BraveObservedHttpHeadersFilterTests {
assertThat(headers.get("b3").get(0)).matches("^" + context.traceId() + "-(.*)-1-" + context.spanId() + "$");
List<FinishedSpan> finishedSpans = testSpanHandler.spans().stream().map(BraveFinishedSpan::new)
.collect(Collectors.toList());
SpansAssert.then(finishedSpans).hasASpanWithName("HTTP GET", spanAssert -> spanAssert
.hasTag("spring.cloud.gateway.route.id", "foo")
.hasTag("http.method", "GET")
SpansAssert.then(finishedSpans).hasASpanWithName("HTTP GET",
spanAssert -> spanAssert.hasTag("spring.cloud.gateway.route.id", "foo").hasTag("http.method", "GET")
.hasTag("http.status_code", "200")
.hasTag("spring.cloud.gateway.route.uri", "http://localhost:8080/")
.hasTag("http.uri", "http://localhost:8080/get"));

4
spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservationClosingWebExceptionHandlerTests.java

@ -52,8 +52,10 @@ class ObservationClosingWebExceptionHandlerTests { @@ -52,8 +52,10 @@ class ObservationClosingWebExceptionHandlerTests {
void shouldStopTheObservationIfItWasNotStoppedPreviouslyAndThereWasAnError() {
Observation observation = Mockito.mock(Observation.class);
exchange.getAttributes().put(ObservedRequestHttpHeadersFilter.CHILD_OBSERVATION, observation);
RuntimeException runtimeException = new RuntimeException();
assertThatNoException().isThrownBy(() -> handler.handle(exchange, new RuntimeException()));
assertThatNoException().isThrownBy(() -> handler.handle(exchange, runtimeException));
Mockito.verify(observation).error(runtimeException);
Mockito.verify(observation).stop();
}

15
spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/headers/observation/ObservedHttpHeadersFilterTests.java

@ -84,17 +84,16 @@ public class ObservedHttpHeadersFilterTests extends SampleTestRunner { @@ -84,17 +84,16 @@ public class ObservedHttpHeadersFilterTests extends SampleTestRunner {
.containsEntry("X-B3-TraceId", Collections.singletonList(context.traceId()))
.doesNotContainEntry("X-B3-SpanId", Collections.singletonList(context.spanId()))
.containsKey("X-B3-SpanId");
SpansAssert.then(bb.getFinishedSpans()).hasASpanWithName("HTTP GET", spanAssert -> spanAssert
.hasTag("http.method", "GET").hasTag("http.status_code", "200")
SpansAssert.then(bb.getFinishedSpans()).hasASpanWithName("HTTP GET",
spanAssert -> spanAssert.hasTag("http.method", "GET").hasTag("http.status_code", "200")
.hasTag("http.uri", "http://localhost:8080/get")
.hasTag("spring.cloud.gateway.route.uri", "http://localhost:8080/")
.hasTag("spring.cloud.gateway.route.id", "foo"));
MeterRegistryAssert.then(meterRegistry)
.hasTimerWithNameAndTags("http.client.requests",
Tags.of("spring.cloud.gateway.route.id", "foo", "error", "none", "http.method", "GET", "http.status_code", "200", "spring.cloud.gateway.route.uri",
"http://localhost:8080/"))
.hasMeterWithNameAndTags("http.client.requests.active",
Tags.of("spring.cloud.gateway.route.id", "foo", "http.method", "GET", "spring.cloud.gateway.route.uri", "http://localhost:8080/"));
MeterRegistryAssert.then(meterRegistry).hasTimerWithNameAndTags("http.client.requests",
Tags.of("spring.cloud.gateway.route.id", "foo", "error", "none", "http.method", "GET",
"http.status_code", "200", "spring.cloud.gateway.route.uri", "http://localhost:8080/"))
.hasMeterWithNameAndTags("http.client.requests.active", Tags.of("spring.cloud.gateway.route.id",
"foo", "http.method", "GET", "spring.cloud.gateway.route.uri", "http://localhost:8080/"));
};
}

Loading…
Cancel
Save