Skip to content

Commit 001b263

Browse files
committed
Reorganize HTTP Observation types
Closes gh-29334
1 parent 4d44aaf commit 001b263

File tree

42 files changed

+762
-849
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+762
-849
lines changed

spring-web/src/main/java/org/springframework/http/client/observation/ClientHttpObservationDocumentation.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525

2626

2727
/**
28-
* Documented {@link io.micrometer.common.KeyValue KeyValues} for {@link ClientHttpRequestFactory HTTP client observations}.
28+
* Documented {@link io.micrometer.common.KeyValue KeyValues} for {@link ClientHttpRequestFactory HTTP client} observations.
2929
* <p>This class is used by automated tools to document KeyValues attached to the HTTP client observations.
30+
*
3031
* @author Brian Clozel
3132
* @since 6.0
3233
*/
@@ -38,7 +39,7 @@ public enum ClientHttpObservationDocumentation implements ObservationDocumentati
3839
HTTP_REQUEST {
3940
@Override
4041
public Class<? extends ObservationConvention<? extends Observation.Context>> getDefaultConvention() {
41-
return DefaultClientHttpObservationConvention.class;
42+
return DefaultClientRequestObservationConvention.class;
4243
}
4344

4445
@Override

spring-web/src/main/java/org/springframework/http/client/observation/ClientHttpObservationContext.java renamed to spring-web/src/main/java/org/springframework/http/client/observation/ClientRequestObservationContext.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,18 @@
1919
import io.micrometer.observation.transport.RequestReplySenderContext;
2020

2121
import org.springframework.http.client.ClientHttpRequest;
22-
import org.springframework.http.client.ClientHttpRequestFactory;
2322
import org.springframework.http.client.ClientHttpResponse;
2423
import org.springframework.lang.Nullable;
2524

2625
/**
2726
* Context that holds information for metadata collection
28-
* during the {@link ClientHttpRequestFactory client HTTP} observations.
27+
* during the {@link ClientHttpObservationDocumentation#HTTP_REQUEST client HTTP exchanges} observations.
2928
* <p>This context also extends {@link RequestReplySenderContext} for propagating tracing
3029
* information with the HTTP client exchange.
3130
* @author Brian Clozel
3231
* @since 6.0
3332
*/
34-
public class ClientHttpObservationContext extends RequestReplySenderContext<ClientHttpRequest, ClientHttpResponse> {
33+
public class ClientRequestObservationContext extends RequestReplySenderContext<ClientHttpRequest, ClientHttpResponse> {
3534

3635
@Nullable
3736
private String uriTemplate;
@@ -40,8 +39,8 @@ public class ClientHttpObservationContext extends RequestReplySenderContext<Clie
4039
* Create an observation context for {@link ClientHttpRequest} observations.
4140
* @param request the HTTP client request
4241
*/
43-
public ClientHttpObservationContext(ClientHttpRequest request) {
44-
super(ClientHttpObservationContext::setRequestHeader);
42+
public ClientRequestObservationContext(ClientHttpRequest request) {
43+
super(ClientRequestObservationContext::setRequestHeader);
4544
this.setCarrier(request);
4645
}
4746

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@
2020
import io.micrometer.observation.ObservationConvention;
2121

2222
/**
23-
* Interface for an {@link ObservationConvention} related to RestTemplate HTTP exchanges.
23+
* Interface for an {@link ObservationConvention} for
24+
* {@link ClientHttpObservationDocumentation#HTTP_REQUEST client HTTP exchanges}.
25+
*
2426
* @author Brian Clozel
2527
* @since 6.0
2628
*/
27-
public interface ClientHttpObservationConvention extends ObservationConvention<ClientHttpObservationContext> {
29+
public interface ClientRequestObservationConvention extends ObservationConvention<ClientRequestObservationContext> {
2830

2931
@Override
3032
default boolean supportsContext(Observation.Context context) {
31-
return context instanceof ClientHttpObservationContext;
33+
return context instanceof ClientRequestObservationContext;
3234
}
3335

3436
}
Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,19 @@
2121
import io.micrometer.common.KeyValue;
2222
import io.micrometer.common.KeyValues;
2323

24+
import org.springframework.http.HttpStatus;
25+
import org.springframework.http.HttpStatusCode;
2426
import org.springframework.http.client.ClientHttpResponse;
25-
import org.springframework.http.observation.HttpOutcome;
2627
import org.springframework.util.StringUtils;
2728

2829
/**
29-
* Default implementation for a {@link ClientHttpObservationConvention},
30-
* extracting information from the {@link ClientHttpObservationContext}.
30+
* Default implementation for a {@link ClientRequestObservationConvention},
31+
* extracting information from the {@link ClientRequestObservationContext}.
3132
*
3233
* @author Brian Clozel
3334
* @since 6.0
3435
*/
35-
public class DefaultClientHttpObservationConvention implements ClientHttpObservationConvention {
36+
public class DefaultClientRequestObservationConvention implements ClientRequestObservationConvention {
3637

3738
private static final String DEFAULT_NAME = "http.client.requests";
3839

@@ -44,26 +45,31 @@ public class DefaultClientHttpObservationConvention implements ClientHttpObserva
4445

4546
private static final KeyValue STATUS_CLIENT_ERROR = KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.STATUS, "CLIENT_ERROR");
4647

48+
private static final KeyValue HTTP_OUTCOME_SUCCESS = KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.OUTCOME, "SUCCESS");
49+
50+
private static final KeyValue HTTP_OUTCOME_UNKNOWN = KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.OUTCOME, "UNKNOWN");
51+
4752
private static final KeyValue EXCEPTION_NONE = KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.EXCEPTION, "none");
4853

4954
private static final KeyValue HTTP_URL_NONE = KeyValue.of(ClientHttpObservationDocumentation.HighCardinalityKeyNames.HTTP_URL, "none");
5055

5156
private static final KeyValue CLIENT_NAME_NONE = KeyValue.of(ClientHttpObservationDocumentation.HighCardinalityKeyNames.CLIENT_NAME, "none");
5257

58+
5359
private final String name;
5460

5561
/**
5662
* Create a convention with the default name {@code "http.client.requests"}.
5763
*/
58-
public DefaultClientHttpObservationConvention() {
64+
public DefaultClientRequestObservationConvention() {
5965
this(DEFAULT_NAME);
6066
}
6167

6268
/**
6369
* Create a convention with a custom name.
6470
* @param name the observation name
6571
*/
66-
public DefaultClientHttpObservationConvention(String name) {
72+
public DefaultClientRequestObservationConvention(String name) {
6773
this.name = name;
6874
}
6975

@@ -73,23 +79,23 @@ public String getName() {
7379
}
7480

7581
@Override
76-
public String getContextualName(ClientHttpObservationContext context) {
82+
public String getContextualName(ClientRequestObservationContext context) {
7783
return "http " + context.getCarrier().getMethod().name().toLowerCase();
7884
}
7985

8086
@Override
81-
public KeyValues getLowCardinalityKeyValues(ClientHttpObservationContext context) {
87+
public KeyValues getLowCardinalityKeyValues(ClientRequestObservationContext context) {
8288
return KeyValues.of(uri(context), method(context), status(context), exception(context), outcome(context));
8389
}
8490

85-
protected KeyValue uri(ClientHttpObservationContext context) {
91+
protected KeyValue uri(ClientRequestObservationContext context) {
8692
if (context.getUriTemplate() != null) {
8793
return KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.URI, context.getUriTemplate());
8894
}
8995
return URI_NONE;
9096
}
9197

92-
protected KeyValue method(ClientHttpObservationContext context) {
98+
protected KeyValue method(ClientRequestObservationContext context) {
9399
if (context.getCarrier() != null) {
94100
return KeyValue.of(ClientHttpObservationDocumentation.LowCardinalityKeyNames.METHOD, context.getCarrier().getMethod().name());
95101
}
@@ -98,7 +104,7 @@ protected KeyValue method(ClientHttpObservationContext context) {
98104
}
99105
}
100106

101-
protected KeyValue status(ClientHttpObservationContext context) {
107+
protected KeyValue status(ClientRequestObservationContext context) {
102108
ClientHttpResponse response = context.getResponse();
103109
if (response == null) {
104110
return STATUS_CLIENT_ERROR;
@@ -111,7 +117,7 @@ protected KeyValue status(ClientHttpObservationContext context) {
111117
}
112118
}
113119

114-
protected KeyValue exception(ClientHttpObservationContext context) {
120+
protected KeyValue exception(ClientRequestObservationContext context) {
115121
Throwable error = context.getError();
116122
if (error != null) {
117123
String simpleName = error.getClass().getSimpleName();
@@ -121,36 +127,51 @@ protected KeyValue exception(ClientHttpObservationContext context) {
121127
return EXCEPTION_NONE;
122128
}
123129

124-
protected static KeyValue outcome(ClientHttpObservationContext context) {
130+
protected static KeyValue outcome(ClientRequestObservationContext context) {
125131
if (context.getResponse() != null) {
126132
try {
127-
HttpOutcome httpOutcome = HttpOutcome.forStatus(context.getResponse().getStatusCode());
128-
return httpOutcome.asKeyValue();
133+
return HttpOutcome.forStatus(context.getResponse().getStatusCode());
129134
}
130135
catch (IOException ex) {
131136
// Continue
132137
}
133138
}
134-
return HttpOutcome.UNKNOWN.asKeyValue();
139+
return HTTP_OUTCOME_UNKNOWN;
135140
}
136141

137142
@Override
138-
public KeyValues getHighCardinalityKeyValues(ClientHttpObservationContext context) {
143+
public KeyValues getHighCardinalityKeyValues(ClientRequestObservationContext context) {
139144
return KeyValues.of(requestUri(context), clientName(context));
140145
}
141146

142-
protected KeyValue requestUri(ClientHttpObservationContext context) {
147+
protected KeyValue requestUri(ClientRequestObservationContext context) {
143148
if (context.getCarrier() != null) {
144149
return KeyValue.of(ClientHttpObservationDocumentation.HighCardinalityKeyNames.HTTP_URL, context.getCarrier().getURI().toASCIIString());
145150
}
146151
return HTTP_URL_NONE;
147152
}
148153

149-
protected KeyValue clientName(ClientHttpObservationContext context) {
154+
protected KeyValue clientName(ClientRequestObservationContext context) {
150155
if (context.getCarrier() != null && context.getCarrier().getURI().getHost() != null) {
151156
return KeyValue.of(ClientHttpObservationDocumentation.HighCardinalityKeyNames.CLIENT_NAME, context.getCarrier().getURI().getHost());
152157
}
153158
return CLIENT_NAME_NONE;
154159
}
155160

161+
static class HttpOutcome {
162+
163+
static KeyValue forStatus(HttpStatusCode statusCode) {
164+
if (statusCode.is2xxSuccessful()) {
165+
return HTTP_OUTCOME_SUCCESS;
166+
}
167+
else if (statusCode instanceof HttpStatus status){
168+
return KeyValue.of("outcome", status.series().name());
169+
}
170+
else {
171+
return HTTP_OUTCOME_UNKNOWN;
172+
}
173+
}
174+
175+
}
176+
156177
}

0 commit comments

Comments
 (0)