Open observation scope in RestClient

Prior to this commit, the `RestClient` instrumentation would create and
close observations for HTTP requests, but would not open an observation
scope for the lifetime of the exchange.
This means that custom `ClientHttpRequestInterceptor` and
`ResponseErrorHandler` would not get access to the current observation
scope in case of tracing, possibly leading to missing trace ids in logs.

This commit ensures that an observation scope is managed for the
lifetime of the HTTP exchange.

Fixes gh-33397
This commit is contained in:
Brian Clozel
2024-08-19 11:41:19 +02:00
parent 0101945708
commit 50be08480d
2 changed files with 77 additions and 6 deletions

View File

@@ -468,6 +468,7 @@ final class DefaultRestClient implements RestClient {
ClientHttpResponse clientResponse = null;
Observation observation = null;
Observation.Scope observationScope = null;
URI uri = null;
try {
if (DefaultRestClient.this.defaultRequest != null) {
@@ -481,6 +482,7 @@ final class DefaultRestClient implements RestClient {
observationContext.setUriTemplate(this.uriTemplate);
observation = ClientHttpObservationDocumentation.HTTP_CLIENT_EXCHANGES.observation(observationConvention,
DEFAULT_OBSERVATION_CONVENTION, () -> observationContext, observationRegistry).start();
observationScope = observation.openScope();
if (this.body != null) {
this.body.writeTo(clientRequest);
}
@@ -489,11 +491,14 @@ final class DefaultRestClient implements RestClient {
}
clientResponse = clientRequest.execute();
observationContext.setResponse(clientResponse);
ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse(clientResponse, observation);
ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse(clientResponse, observation, observationScope);
return exchangeFunction.exchange(clientRequest, convertibleWrapper);
}
catch (IOException ex) {
ResourceAccessException resourceAccessException = createResourceAccessException(uri, this.httpMethod, ex);
if (observationScope != null) {
observationScope.close();
}
if (observation != null) {
observation.error(resourceAccessException);
observation.stop();
@@ -501,6 +506,9 @@ final class DefaultRestClient implements RestClient {
throw resourceAccessException;
}
catch (Throwable error) {
if (observationScope != null) {
observationScope.close();
}
if (observation != null) {
observation.error(error);
observation.stop();
@@ -510,6 +518,9 @@ final class DefaultRestClient implements RestClient {
finally {
if (close && clientResponse != null) {
clientResponse.close();
if (observationScope != null) {
observationScope.close();
}
if (observation != null) {
observation.stop();
}
@@ -720,10 +731,12 @@ final class DefaultRestClient implements RestClient {
private final Observation observation;
private final Observation.Scope observationScope;
public DefaultConvertibleClientHttpResponse(ClientHttpResponse delegate, Observation observation) {
public DefaultConvertibleClientHttpResponse(ClientHttpResponse delegate, Observation observation, Observation.Scope observationScope) {
this.delegate = delegate;
this.observation = observation;
this.observationScope = observationScope;
}
@@ -764,6 +777,7 @@ final class DefaultRestClient implements RestClient {
@Override
public void close() {
this.delegate.close();
this.observationScope.close();
this.observation.stop();
}