Polish observability changes
Closes gh-29235
This commit is contained in:
@@ -56,7 +56,7 @@ public enum ClientHttpObservation implements DocumentedObservation {
|
||||
public enum LowCardinalityKeyNames implements KeyName {
|
||||
|
||||
/**
|
||||
* Name of HTTP request method or {@code "None"} if the request could not be created.
|
||||
* Name of HTTP request method or {@code "none"} if the request could not be created.
|
||||
*/
|
||||
METHOD {
|
||||
@Override
|
||||
@@ -67,7 +67,7 @@ public enum ClientHttpObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* URI template used for HTTP request, or {@code ""} if none was provided.
|
||||
* URI template used for HTTP request, or {@code "none"} if none was provided.
|
||||
*/
|
||||
URI {
|
||||
@Override
|
||||
@@ -88,7 +88,7 @@ public enum ClientHttpObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* Name of the exception thrown during the exchange, or {@code "None"} if no exception happened.
|
||||
* Name of the exception thrown during the exchange, or {@code "none"} if no exception happened.
|
||||
*/
|
||||
EXCEPTION {
|
||||
@Override
|
||||
|
||||
@@ -23,7 +23,6 @@ import io.micrometer.common.KeyValues;
|
||||
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.observation.HttpOutcome;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -41,10 +40,16 @@ public class DefaultClientHttpObservationConvention implements ClientHttpObserva
|
||||
|
||||
private static final KeyValue METHOD_NONE = KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.METHOD, "none");
|
||||
|
||||
private static final KeyValue STATUS_IO_ERROR = KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.STATUS, "IO_ERROR");
|
||||
|
||||
private static final KeyValue STATUS_CLIENT_ERROR = KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.STATUS, "CLIENT_ERROR");
|
||||
|
||||
private static final KeyValue EXCEPTION_NONE = KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.EXCEPTION, "none");
|
||||
|
||||
private static final KeyValue URI_EXPANDED_NONE = KeyValue.of(ClientHttpObservation.HighCardinalityKeyNames.URI_EXPANDED, "none");
|
||||
|
||||
private static final KeyValue CLIENT_NAME_NONE = KeyValue.of(ClientHttpObservation.HighCardinalityKeyNames.CLIENT_NAME, "none");
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
@@ -94,18 +99,15 @@ public class DefaultClientHttpObservationConvention implements ClientHttpObserva
|
||||
}
|
||||
|
||||
protected KeyValue status(ClientHttpObservationContext context) {
|
||||
return KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.STATUS, getStatusMessage(context.getResponse()));
|
||||
}
|
||||
|
||||
private String getStatusMessage(@Nullable ClientHttpResponse response) {
|
||||
ClientHttpResponse response = context.getResponse();
|
||||
if (response == null) {
|
||||
return STATUS_CLIENT_ERROR;
|
||||
}
|
||||
try {
|
||||
if (response == null) {
|
||||
return "CLIENT_ERROR";
|
||||
}
|
||||
return String.valueOf(response.getStatusCode().value());
|
||||
return KeyValue.of(ClientHttpObservation.LowCardinalityKeyNames.STATUS, String.valueOf(response.getStatusCode().value()));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return "IO_ERROR";
|
||||
return STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,14 +120,14 @@ public class DefaultClientHttpObservationConvention implements ClientHttpObserva
|
||||
}
|
||||
|
||||
protected static KeyValue outcome(ClientHttpObservationContext context) {
|
||||
try {
|
||||
if (context.getResponse() != null) {
|
||||
if (context.getResponse() != null) {
|
||||
try {
|
||||
HttpOutcome httpOutcome = HttpOutcome.forStatus(context.getResponse().getStatusCode());
|
||||
return httpOutcome.asKeyValue();
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Continue
|
||||
catch (IOException ex) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
return HttpOutcome.UNKNOWN.asKeyValue();
|
||||
}
|
||||
@@ -143,11 +145,10 @@ public class DefaultClientHttpObservationConvention implements ClientHttpObserva
|
||||
}
|
||||
|
||||
protected KeyValue clientName(ClientHttpObservationContext context) {
|
||||
String host = "none";
|
||||
if (context.getCarrier() != null && context.getCarrier().getURI().getHost() != null) {
|
||||
host = context.getCarrier().getURI().getHost();
|
||||
return KeyValue.of(ClientHttpObservation.HighCardinalityKeyNames.CLIENT_NAME, context.getCarrier().getURI().getHost());
|
||||
}
|
||||
return KeyValue.of(ClientHttpObservation.HighCardinalityKeyNames.CLIENT_NAME, host);
|
||||
return CLIENT_NAME_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ import org.springframework.http.HttpStatusCode;
|
||||
|
||||
/**
|
||||
* The outcome of an HTTP request.
|
||||
* <p>Used as the {@code "outcome} {@link io.micrometer.common.KeyValue}
|
||||
* <p>Used as the {@code "outcome"} {@link io.micrometer.common.KeyValue}
|
||||
* for HTTP {@link io.micrometer.observation.Observation observations}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Andy Wilkinson
|
||||
* @since 6.0.0
|
||||
* @since 6.0
|
||||
*/
|
||||
public enum HttpOutcome {
|
||||
|
||||
|
||||
@@ -653,7 +653,7 @@ public interface RestOperations {
|
||||
* Execute the HTTP method to the given URI template, preparing the request with the
|
||||
* {@link RequestCallback}, and reading the response with a {@link ResponseExtractor}.
|
||||
* <p>URI Template variables are expanded using the given URI variables, if any.
|
||||
* @param url the URL
|
||||
* @param uriTemplate the URI template
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
@@ -661,7 +661,7 @@ public interface RestOperations {
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
*/
|
||||
@Nullable
|
||||
<T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
|
||||
<T> T execute(String uriTemplate, HttpMethod method, @Nullable RequestCallback requestCallback,
|
||||
@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
@@ -669,7 +669,7 @@ public interface RestOperations {
|
||||
* Execute the HTTP method to the given URI template, preparing the request with the
|
||||
* {@link RequestCallback}, and reading the response with a {@link ResponseExtractor}.
|
||||
* <p>URI Template variables are expanded using the given URI variables map.
|
||||
* @param url the URL
|
||||
* @param uriTemplate the URI template
|
||||
* @param method the HTTP method (GET, POST, etc)
|
||||
* @param requestCallback object that prepares the request
|
||||
* @param responseExtractor object that extracts the return value from the response
|
||||
@@ -677,7 +677,7 @@ public interface RestOperations {
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
*/
|
||||
@Nullable
|
||||
<T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
|
||||
<T> T execute(String uriTemplate, HttpMethod method, @Nullable RequestCallback requestCallback,
|
||||
@Nullable ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables)
|
||||
throws RestClientException;
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
|
||||
/**
|
||||
* Configure an {@link ObservationRegistry} for collecting spans and metrics
|
||||
* for request execution. By default, {@link Observation} are No-Ops.
|
||||
* for request execution. By default, {@link Observation observations} are no-ops.
|
||||
* @param observationRegistry the observation registry to use
|
||||
* @since 6.0
|
||||
*/
|
||||
@@ -830,6 +830,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
* @param requestCallback object that prepares the request (can be {@code null})
|
||||
* @param responseExtractor object that extracts the return value from the response (can be {@code null})
|
||||
* @return an arbitrary object, as returned by the {@link ResponseExtractor}
|
||||
* @since 6.0
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("try")
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.micrometer.common.KeyValues;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.observation.HttpOutcome;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default {@link HttpRequestsObservationConvention}.
|
||||
@@ -118,9 +119,12 @@ public class DefaultHttpRequestsObservationConvention implements HttpRequestsObs
|
||||
}
|
||||
|
||||
protected KeyValue exception(HttpRequestsObservationContext context) {
|
||||
return context.getError().map(throwable ->
|
||||
KeyValue.of(HttpRequestsObservation.LowCardinalityKeyNames.EXCEPTION, throwable.getClass().getSimpleName()))
|
||||
.orElse(EXCEPTION_NONE);
|
||||
return context.getError().map(throwable -> {
|
||||
String simpleName = throwable.getClass().getSimpleName();
|
||||
return KeyValue.of(HttpRequestsObservation.LowCardinalityKeyNames.EXCEPTION,
|
||||
StringUtils.hasText(simpleName) ? simpleName : throwable.getClass().getName());
|
||||
})
|
||||
.orElse(EXCEPTION_NONE);
|
||||
}
|
||||
|
||||
protected KeyValue outcome(HttpRequestsObservationContext context) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
public enum LowCardinalityKeyNames implements KeyName {
|
||||
|
||||
/**
|
||||
* Name of HTTP request method or {@code "None"} if the request was not received properly.
|
||||
* Name of HTTP request method or {@code "none"} if the request was not received properly.
|
||||
*/
|
||||
METHOD {
|
||||
@Override
|
||||
@@ -65,7 +65,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* HTTP response raw status code, or {@code "STATUS_UNKNOWN"} if no response was created.
|
||||
* HTTP response raw status code, or {@code "UNKNOWN"} if no response was created.
|
||||
*/
|
||||
STATUS {
|
||||
@Override
|
||||
@@ -87,7 +87,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* Name of the exception thrown during the exchange, or {@code "None"} if no exception happened.
|
||||
* Name of the exception thrown during the exchange, or {@code "none"} if no exception happened.
|
||||
*/
|
||||
EXCEPTION {
|
||||
@Override
|
||||
|
||||
@@ -36,8 +36,8 @@ public class HttpRequestsObservationContext extends RequestReplyReceiverContext<
|
||||
|
||||
public HttpRequestsObservationContext(HttpServletRequest request, HttpServletResponse response) {
|
||||
super(HttpServletRequest::getHeader);
|
||||
this.setCarrier(request);
|
||||
this.setResponse(response);
|
||||
setCarrier(request);
|
||||
setResponse(response);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
* for HTTP exchanges. This collects information about the execution time and
|
||||
* information gathered from the {@link HttpRequestsObservationContext}.
|
||||
* <p>Web Frameworks can fetch the current {@link HttpRequestsObservationContext context}
|
||||
* as a {@link #CURRENT_OBSERVATION_ATTRIBUTE request attribute} and contribute
|
||||
* as a {@link #CURRENT_OBSERVATION_CONTEXT_ATTRIBUTE request attribute} and contribute
|
||||
* additional information to it.
|
||||
* The configured {@link HttpRequestsObservationConvention} will use this context to collect
|
||||
* {@link io.micrometer.common.KeyValue metadata} and attach it to the observation.
|
||||
@@ -61,17 +61,17 @@ public class HttpRequestsObservationFilter extends OncePerRequestFilter {
|
||||
private final HttpRequestsObservationConvention observationConvention;
|
||||
|
||||
/**
|
||||
* Create a {@code HttpRequestsObservationFilter} that records observations
|
||||
* Create an {@code HttpRequestsObservationFilter} that records observations
|
||||
* against the given {@link ObservationRegistry}. The default
|
||||
* {@link DefaultHttpRequestsObservationConvention convention} will be used.
|
||||
* @param observationRegistry the registry to use for recording observations
|
||||
*/
|
||||
public HttpRequestsObservationFilter(ObservationRegistry observationRegistry) {
|
||||
this(observationRegistry, new DefaultHttpRequestsObservationConvention());
|
||||
this(observationRegistry, DEFAULT_OBSERVATION_CONVENTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code HttpRequestsObservationFilter} that records observations
|
||||
* Create an {@code HttpRequestsObservationFilter} that records observations
|
||||
* against the given {@link ObservationRegistry} with a custom convention.
|
||||
* @param observationRegistry the registry to use for recording observations
|
||||
* @param observationConvention the convention to use for all recorded observations
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.micrometer.common.KeyValues;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.observation.HttpOutcome;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
/**
|
||||
@@ -92,6 +93,9 @@ public class DefaultHttpRequestsObservationConvention implements HttpRequestsObs
|
||||
}
|
||||
|
||||
protected KeyValue status(HttpRequestsObservationContext context) {
|
||||
if (context.isConnectionAborted()) {
|
||||
return STATUS_UNKNOWN;
|
||||
}
|
||||
return (context.getResponse() != null) ? KeyValue.of(HttpRequestsObservation.LowCardinalityKeyNames.STATUS, Integer.toString(context.getResponse().getStatusCode().value())) : STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -120,16 +124,19 @@ public class DefaultHttpRequestsObservationConvention implements HttpRequestsObs
|
||||
}
|
||||
|
||||
protected KeyValue exception(HttpRequestsObservationContext context) {
|
||||
return context.getError().map(throwable ->
|
||||
KeyValue.of(HttpRequestsObservation.LowCardinalityKeyNames.EXCEPTION, throwable.getClass().getSimpleName()))
|
||||
.orElse(EXCEPTION_NONE);
|
||||
return context.getError().map(throwable -> {
|
||||
String simpleName = throwable.getClass().getSimpleName();
|
||||
return KeyValue.of(HttpRequestsObservation.LowCardinalityKeyNames.EXCEPTION,
|
||||
StringUtils.hasText(simpleName) ? simpleName : throwable.getClass().getName());
|
||||
})
|
||||
.orElse(EXCEPTION_NONE);
|
||||
}
|
||||
|
||||
protected KeyValue outcome(HttpRequestsObservationContext context) {
|
||||
if (context.isConnectionAborted()) {
|
||||
return HttpOutcome.UNKNOWN.asKeyValue();
|
||||
}
|
||||
else if (context.getResponse() != null) {
|
||||
if (context.getResponse() != null) {
|
||||
HttpOutcome httpOutcome = HttpOutcome.forStatus(context.getResponse().getStatusCode());
|
||||
return httpOutcome.asKeyValue();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import io.micrometer.observation.docs.DocumentedObservation;
|
||||
|
||||
/**
|
||||
* Documented {@link io.micrometer.common.KeyValue KeyValues} for the HTTP server observations
|
||||
* for Servlet-based web applications.
|
||||
* for reactive web applications.
|
||||
* <p>This class is used by automated tools to document KeyValues attached to the HTTP server observations.
|
||||
* @author Brian Clozel
|
||||
* @since 6.0
|
||||
@@ -54,7 +54,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
public enum LowCardinalityKeyNames implements KeyName {
|
||||
|
||||
/**
|
||||
* Name of HTTP request method or {@code "None"} if the request was not received properly.
|
||||
* Name of HTTP request method or {@code "none"} if the request was not received properly.
|
||||
*/
|
||||
METHOD {
|
||||
@Override
|
||||
@@ -65,7 +65,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* HTTP response raw status code, or {@code "STATUS_UNKNOWN"} if no response was created.
|
||||
* HTTP response raw status code, or {@code "UNKNOWN"} if no response was created.
|
||||
*/
|
||||
STATUS {
|
||||
@Override
|
||||
@@ -87,7 +87,7 @@ public enum HttpRequestsObservation implements DocumentedObservation {
|
||||
},
|
||||
|
||||
/**
|
||||
* Name of the exception thrown during the exchange, or {@code "None"} if no exception happened.
|
||||
* Name of the exception thrown during the exchange, or {@code "none"} if no exception happened.
|
||||
*/
|
||||
EXCEPTION {
|
||||
@Override
|
||||
|
||||
@@ -40,8 +40,8 @@ public class HttpRequestsObservationContext extends RequestReplyReceiverContext<
|
||||
|
||||
public HttpRequestsObservationContext(ServerWebExchange exchange) {
|
||||
super((request, key) -> request.getHeaders().getFirst(key));
|
||||
this.setCarrier(exchange.getRequest());
|
||||
this.setResponse(exchange.getResponse());
|
||||
setCarrier(exchange.getRequest());
|
||||
setResponse(exchange.getResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public class HttpRequestsObservationContext extends RequestReplyReceiverContext<
|
||||
|
||||
/**
|
||||
* Whether the current connection was aborted by the client, resulting
|
||||
* in a {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on te reactive chain,
|
||||
* in a {@link reactor.core.publisher.SignalType#CANCEL cancel signal} on the reactive chain,
|
||||
* or an {@code AbortedException} when reading the request.
|
||||
* @return if the connection has been aborted
|
||||
*/
|
||||
|
||||
@@ -60,17 +60,17 @@ public class HttpRequestsObservationWebFilter implements WebFilter {
|
||||
private final HttpRequestsObservationConvention observationConvention;
|
||||
|
||||
/**
|
||||
* Create a {@code HttpRequestsObservationWebFilter} that records observations
|
||||
* Create an {@code HttpRequestsObservationWebFilter} that records observations
|
||||
* against the given {@link ObservationRegistry}. The default
|
||||
* {@link DefaultHttpRequestsObservationConvention convention} will be used.
|
||||
* @param observationRegistry the registry to use for recording observations
|
||||
*/
|
||||
public HttpRequestsObservationWebFilter(ObservationRegistry observationRegistry) {
|
||||
this(observationRegistry, new DefaultHttpRequestsObservationConvention());
|
||||
this(observationRegistry, DEFAULT_OBSERVATION_CONVENTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code HttpRequestsObservationWebFilter} that records observations
|
||||
* Create an {@code HttpRequestsObservationWebFilter} that records observations
|
||||
* against the given {@link ObservationRegistry} with a custom convention.
|
||||
* @param observationRegistry the registry to use for recording observations
|
||||
* @param observationConvention the convention to use for all recorded observations
|
||||
|
||||
Reference in New Issue
Block a user