Allow custom observation convention for RestClient
This commit allows to use a custom `ObservationConvention` in the `DefaultRestClient`, and to set it through the `RestClient.Builder`. Closes gh-31325
This commit is contained in:
parent
c356ce2637
commit
9cab6c90a9
|
@ -107,6 +107,9 @@ final class DefaultRestClient implements RestClient {
|
|||
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
@Nullable
|
||||
private final ClientRequestObservationConvention observationConvention;
|
||||
|
||||
|
||||
DefaultRestClient(ClientHttpRequestFactory clientRequestFactory,
|
||||
@Nullable List<ClientHttpRequestInterceptor> interceptors,
|
||||
|
@ -116,6 +119,7 @@ final class DefaultRestClient implements RestClient {
|
|||
@Nullable List<StatusHandler> statusHandlers,
|
||||
List<HttpMessageConverter<?>> messageConverters,
|
||||
ObservationRegistry observationRegistry,
|
||||
@Nullable ClientRequestObservationConvention observationConvention,
|
||||
DefaultRestClientBuilder builder) {
|
||||
|
||||
this.clientRequestFactory = clientRequestFactory;
|
||||
|
@ -126,6 +130,7 @@ final class DefaultRestClient implements RestClient {
|
|||
this.defaultStatusHandlers = (statusHandlers != null ? new ArrayList<>(statusHandlers) : new ArrayList<>());
|
||||
this.messageConverters = messageConverters;
|
||||
this.observationRegistry = observationRegistry;
|
||||
this.observationConvention = observationConvention;
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
|
@ -393,7 +398,7 @@ final class DefaultRestClient implements RestClient {
|
|||
clientRequest.getHeaders().addAll(headers);
|
||||
ClientRequestObservationContext observationContext = new ClientRequestObservationContext(clientRequest);
|
||||
observationContext.setUriTemplate((String) this.attributes.get(URI_TEMPLATE_ATTRIBUTE));
|
||||
observation = ClientHttpObservationDocumentation.HTTP_CLIENT_EXCHANGES.observation(null,
|
||||
observation = ClientHttpObservationDocumentation.HTTP_CLIENT_EXCHANGES.observation(observationConvention,
|
||||
DEFAULT_OBSERVATION_CONVENTION, () -> observationContext, observationRegistry).start();
|
||||
if (this.body != null) {
|
||||
this.body.writeTo(clientRequest);
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
|||
import org.springframework.http.client.JdkClientHttpRequestFactory;
|
||||
import org.springframework.http.client.JettyClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.client.observation.ClientRequestObservationConvention;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
|
@ -132,6 +133,9 @@ final class DefaultRestClientBuilder implements RestClient.Builder {
|
|||
|
||||
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
|
||||
|
||||
@Nullable
|
||||
private ClientRequestObservationConvention observationConvention;
|
||||
|
||||
|
||||
public DefaultRestClientBuilder() {
|
||||
}
|
||||
|
@ -161,6 +165,7 @@ final class DefaultRestClientBuilder implements RestClient.Builder {
|
|||
this.interceptors = (other.interceptors != null) ? new ArrayList<>(other.interceptors) : null;
|
||||
this.initializers = (other.initializers != null) ? new ArrayList<>(other.initializers) : null;
|
||||
this.observationRegistry = other.observationRegistry;
|
||||
this.observationConvention = other.observationConvention;
|
||||
}
|
||||
|
||||
public DefaultRestClientBuilder(RestTemplate restTemplate) {
|
||||
|
@ -182,6 +187,7 @@ final class DefaultRestClientBuilder implements RestClient.Builder {
|
|||
this.initializers = new ArrayList<>(restTemplate.getClientHttpRequestInitializers());
|
||||
}
|
||||
this.observationRegistry = restTemplate.getObservationRegistry();
|
||||
this.observationConvention = restTemplate.getObservationConvention();
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,6 +313,12 @@ final class DefaultRestClientBuilder implements RestClient.Builder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestClient.Builder observationConvention(ClientRequestObservationConvention observationConvention) {
|
||||
this.observationConvention = observationConvention;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestClient.Builder apply(Consumer<RestClient.Builder> builderConsumer) {
|
||||
builderConsumer.accept(this);
|
||||
|
@ -362,6 +374,7 @@ final class DefaultRestClientBuilder implements RestClient.Builder {
|
|||
this.statusHandlers,
|
||||
messageConverters,
|
||||
this.observationRegistry,
|
||||
this.observationConvention,
|
||||
new DefaultRestClientBuilder(this)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.springframework.http.client.ClientHttpRequestFactory;
|
|||
import org.springframework.http.client.ClientHttpRequestInitializer;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.observation.ClientRequestObservationConvention;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
|
@ -374,6 +375,16 @@ public interface RestClient {
|
|||
*/
|
||||
Builder observationRegistry(ObservationRegistry observationRegistry);
|
||||
|
||||
/**
|
||||
* Configure the {@link io.micrometer.observation.ObservationConvention} to use
|
||||
* for collecting metadata for the request observation. Will use
|
||||
* {@link org.springframework.http.client.observation.DefaultClientRequestObservationConvention}
|
||||
* if none provided.
|
||||
* @param observationConvention the observation convention to use
|
||||
* @return this builder
|
||||
*/
|
||||
Builder observationConvention(ClientRequestObservationConvention observationConvention);
|
||||
|
||||
/**
|
||||
* Apply the given {@code Consumer} to this builder instance.
|
||||
* <p>This can be useful for applying pre-packaged customizations.
|
||||
|
|
|
@ -375,6 +375,15 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
|||
this.observationConvention = observationConvention;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured {@link ClientRequestObservationConvention}, or {@code null} if not set.
|
||||
* @since 6.1
|
||||
*/
|
||||
@Nullable
|
||||
public ClientRequestObservationConvention getObservationConvention() {
|
||||
return this.observationConvention;
|
||||
}
|
||||
|
||||
// GET
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.springframework.http.client.ClientHttpRequest;
|
|||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.observation.ClientRequestObservationContext;
|
||||
import org.springframework.http.client.observation.ClientRequestObservationConvention;
|
||||
import org.springframework.http.client.observation.DefaultClientRequestObservationConvention;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -159,6 +161,20 @@ class RestClientObservationTests {
|
|||
assertThatHttpObservation().hasLowCardinalityKeyValue("outcome", "UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeWithCustomConventionUsesCustomObservationName() throws Exception {
|
||||
ClientRequestObservationConvention observationConvention =
|
||||
new DefaultClientRequestObservationConvention("custom.requests");
|
||||
RestClient restClient = this.client.mutate().observationConvention(observationConvention).build();
|
||||
mockSentRequest(GET, "https://example.org");
|
||||
mockResponseStatus(HttpStatus.OK);
|
||||
|
||||
restClient.get().uri("https://example.org").retrieve().toBodilessEntity();
|
||||
|
||||
TestObservationRegistryAssert.assertThat(this.observationRegistry)
|
||||
.hasObservationWithNameEqualTo("custom.requests");
|
||||
}
|
||||
|
||||
|
||||
private void mockSentRequest(HttpMethod method, String uri) throws Exception {
|
||||
mockSentRequest(method, uri, new HttpHeaders());
|
||||
|
|
Loading…
Reference in New Issue