Extract HTTP client experimental metrics to a separate class (#8769)
This commit is contained in:
parent
62ca215297
commit
59e2da5aa3
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.api.instrumenter.http;
|
||||
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpRequestBodySize;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpResponseBodySize;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
|
||||
import static java.util.logging.Level.FINE;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.LongHistogram;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.ContextKey;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* {@link OperationListener} which keeps track of <a
|
||||
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-client">non-stable
|
||||
* HTTP client metrics</a>: <a
|
||||
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpclientrequestsize">the
|
||||
* request size </a> and the <a
|
||||
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpclientresponsesize">
|
||||
* the response size</a>.
|
||||
*/
|
||||
public final class HttpClientExperimentalMetrics implements OperationListener {
|
||||
|
||||
private static final ContextKey<Attributes> HTTP_CLIENT_REQUEST_METRICS_START_ATTRIBUTES =
|
||||
ContextKey.named("http-client-experimental-metrics-start-attributes");
|
||||
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(HttpClientExperimentalMetrics.class.getName());
|
||||
|
||||
/**
|
||||
* Returns a {@link OperationMetrics} which can be used to enable recording of {@link
|
||||
* HttpClientExperimentalMetrics} on an {@link
|
||||
* io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder}.
|
||||
*/
|
||||
public static OperationMetrics get() {
|
||||
return HttpClientExperimentalMetrics::new;
|
||||
}
|
||||
|
||||
private final LongHistogram requestSize;
|
||||
private final LongHistogram responseSize;
|
||||
|
||||
private HttpClientExperimentalMetrics(Meter meter) {
|
||||
requestSize =
|
||||
meter
|
||||
.histogramBuilder("http.client.request.size")
|
||||
.setUnit("By")
|
||||
.setDescription("The size of HTTP request messages")
|
||||
.ofLongs()
|
||||
.build();
|
||||
responseSize =
|
||||
meter
|
||||
.histogramBuilder("http.client.response.size")
|
||||
.setUnit("By")
|
||||
.setDescription("The size of HTTP response messages")
|
||||
.ofLongs()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context onStart(Context context, Attributes startAttributes, long startNanos) {
|
||||
return context.with(HTTP_CLIENT_REQUEST_METRICS_START_ATTRIBUTES, startAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(Context context, Attributes endAttributes, long endNanos) {
|
||||
Attributes startAttributes = context.get(HTTP_CLIENT_REQUEST_METRICS_START_ATTRIBUTES);
|
||||
if (startAttributes == null) {
|
||||
logger.log(
|
||||
FINE,
|
||||
"No state present when ending context {0}. Cannot record HTTP request metrics.",
|
||||
context);
|
||||
return;
|
||||
}
|
||||
|
||||
Attributes sizeAttributes = applyClientDurationAndSizeView(startAttributes, endAttributes);
|
||||
|
||||
Long requestBodySize = getHttpRequestBodySize(endAttributes, startAttributes);
|
||||
if (requestBodySize != null) {
|
||||
requestSize.record(requestBodySize, sizeAttributes, context);
|
||||
}
|
||||
|
||||
Long responseBodySize = getHttpResponseBodySize(endAttributes, startAttributes);
|
||||
if (responseBodySize != null) {
|
||||
responseSize.record(responseBodySize, sizeAttributes, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.api.instrumenter.http;
|
||||
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpRequestBodySize;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMessageBodySizeUtil.getHttpResponseBodySize;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.createDurationHistogram;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.HttpMetricsUtil.nanosToUnit;
|
||||
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
|
||||
|
|
@ -15,7 +13,6 @@ import static java.util.logging.Level.FINE;
|
|||
import com.google.auto.value.AutoValue;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.DoubleHistogram;
|
||||
import io.opentelemetry.api.metrics.LongHistogram;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.ContextKey;
|
||||
|
|
@ -31,7 +28,7 @@ import java.util.logging.Logger;
|
|||
public final class HttpClientMetrics implements OperationListener {
|
||||
|
||||
private static final ContextKey<State> HTTP_CLIENT_REQUEST_METRICS_STATE =
|
||||
ContextKey.named("http-client-request-metrics-state");
|
||||
ContextKey.named("http-client-metrics-state");
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HttpClientMetrics.class.getName());
|
||||
|
||||
|
|
@ -45,27 +42,11 @@ public final class HttpClientMetrics implements OperationListener {
|
|||
}
|
||||
|
||||
private final DoubleHistogram duration;
|
||||
private final LongHistogram requestSize;
|
||||
private final LongHistogram responseSize;
|
||||
|
||||
private HttpClientMetrics(Meter meter) {
|
||||
duration =
|
||||
createDurationHistogram(
|
||||
meter, "http.client.duration", "The duration of the outbound HTTP request");
|
||||
requestSize =
|
||||
meter
|
||||
.histogramBuilder("http.client.request.size")
|
||||
.setUnit("By")
|
||||
.setDescription("The size of HTTP request messages")
|
||||
.ofLongs()
|
||||
.build();
|
||||
responseSize =
|
||||
meter
|
||||
.histogramBuilder("http.client.response.size")
|
||||
.setUnit("By")
|
||||
.setDescription("The size of HTTP response messages")
|
||||
.ofLongs()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -90,16 +71,6 @@ public final class HttpClientMetrics implements OperationListener {
|
|||
applyClientDurationAndSizeView(state.startAttributes(), endAttributes);
|
||||
duration.record(
|
||||
nanosToUnit(endNanos - state.startTimeNanos()), durationAndSizeAttributes, context);
|
||||
|
||||
Long requestBodySize = getHttpRequestBodySize(endAttributes, state.startAttributes());
|
||||
if (requestBodySize != null) {
|
||||
requestSize.record(requestBodySize, durationAndSizeAttributes, context);
|
||||
}
|
||||
|
||||
Long responseBodySize = getHttpResponseBodySize(endAttributes, state.startAttributes());
|
||||
if (responseBodySize != null) {
|
||||
responseSize.record(responseBodySize, durationAndSizeAttributes, context);
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.api.instrumenter.http;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.SpanContext;
|
||||
import io.opentelemetry.api.trace.TraceFlags;
|
||||
import io.opentelemetry.api.trace.TraceState;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.internal.NetAttributes;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class HttpClientExperimentalMetricsTest {
|
||||
|
||||
@Test
|
||||
void collectsMetrics() {
|
||||
InMemoryMetricReader metricReader = InMemoryMetricReader.create();
|
||||
SdkMeterProvider meterProvider =
|
||||
SdkMeterProvider.builder().registerMetricReader(metricReader).build();
|
||||
|
||||
OperationListener listener =
|
||||
HttpClientExperimentalMetrics.get().create(meterProvider.get("test"));
|
||||
|
||||
Attributes requestAttributes =
|
||||
Attributes.builder()
|
||||
.put("http.method", "GET")
|
||||
.put("http.url", "https://localhost:1234/")
|
||||
.put("http.target", "/")
|
||||
.put("http.scheme", "https")
|
||||
.put("net.peer.name", "localhost")
|
||||
.put("net.peer.port", 1234)
|
||||
.put("http.request_content_length", 100)
|
||||
.build();
|
||||
|
||||
Attributes responseAttributes =
|
||||
Attributes.builder()
|
||||
.put("http.status_code", 200)
|
||||
.put("http.response_content_length", 200)
|
||||
.put(NetAttributes.NET_PROTOCOL_NAME, "http")
|
||||
.put(NetAttributes.NET_PROTOCOL_VERSION, "2.0")
|
||||
.put("net.sock.peer.addr", "1.2.3.4")
|
||||
.put("net.sock.peer.name", "somehost20")
|
||||
.put("net.sock.peer.port", 8080)
|
||||
.build();
|
||||
|
||||
Context parent =
|
||||
Context.root()
|
||||
.with(
|
||||
Span.wrap(
|
||||
SpanContext.create(
|
||||
"ff01020304050600ff0a0b0c0d0e0f00",
|
||||
"090a0b0c0d0e0f00",
|
||||
TraceFlags.getSampled(),
|
||||
TraceState.getDefault())));
|
||||
|
||||
Context context1 = listener.onStart(parent, requestAttributes, nanos(100));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics()).isEmpty();
|
||||
|
||||
Context context2 = listener.onStart(Context.root(), requestAttributes, nanos(150));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics()).isEmpty();
|
||||
|
||||
listener.onEnd(context1, responseAttributes, nanos(250));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(100 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_NAME, "http"),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, "localhost"),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, 1234),
|
||||
equalTo(
|
||||
SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(200 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_NAME, "http"),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, "localhost"),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, 1234),
|
||||
equalTo(
|
||||
SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))));
|
||||
|
||||
listener.onEnd(context2, responseAttributes, nanos(300));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(200 /* bytes */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(400 /* bytes */))));
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
return TimeUnit.MILLISECONDS.toNanos(millis);
|
||||
}
|
||||
}
|
||||
|
|
@ -106,55 +106,7 @@ class HttpClientMetricsTest {
|
|||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00"))
|
||||
.hasBucketBoundaries(DEFAULT_BUCKETS))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(100 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_NAME, "http"),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, "localhost"),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, 1234),
|
||||
equalTo(
|
||||
SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(200 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
|
||||
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_NAME, "http"),
|
||||
equalTo(NetAttributes.NET_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(SemanticAttributes.NET_PEER_NAME, "localhost"),
|
||||
equalTo(SemanticAttributes.NET_PEER_PORT, 1234),
|
||||
equalTo(
|
||||
SemanticAttributes.NET_SOCK_PEER_ADDR, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))));
|
||||
.hasBucketBoundaries(DEFAULT_BUCKETS))));
|
||||
|
||||
listener.onEnd(context2, responseAttributes, nanos(300));
|
||||
|
||||
|
|
@ -165,19 +117,8 @@ class HttpClientMetricsTest {
|
|||
.hasName("http.client.duration")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(300 /* millis */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(200 /* bytes */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(400 /* bytes */))));
|
||||
histogram.hasPointsSatisfying(
|
||||
point -> point.hasSum(300 /* millis */))));
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.api.instrumenter.http;
|
||||
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
|
||||
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.SpanContext;
|
||||
import io.opentelemetry.api.trace.TraceFlags;
|
||||
import io.opentelemetry.api.trace.TraceState;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.NetworkAttributes;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.url.internal.UrlAttributes;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class HttpClientExperimentalMetricsStableSemconvTest {
|
||||
|
||||
@Test
|
||||
void collectsMetrics() {
|
||||
InMemoryMetricReader metricReader = InMemoryMetricReader.create();
|
||||
SdkMeterProvider meterProvider =
|
||||
SdkMeterProvider.builder().registerMetricReader(metricReader).build();
|
||||
|
||||
OperationListener listener =
|
||||
HttpClientExperimentalMetrics.get().create(meterProvider.get("test"));
|
||||
|
||||
Attributes requestAttributes =
|
||||
Attributes.builder()
|
||||
.put(HttpAttributes.HTTP_REQUEST_METHOD, "GET")
|
||||
.put(UrlAttributes.URL_FULL, "https://localhost:1234/")
|
||||
.put(UrlAttributes.URL_SCHEME, "https")
|
||||
.put(UrlAttributes.URL_PATH, "/")
|
||||
.put(UrlAttributes.URL_QUERY, "q=a")
|
||||
.put(NetworkAttributes.SERVER_ADDRESS, "localhost")
|
||||
.put(NetworkAttributes.SERVER_PORT, 1234)
|
||||
.build();
|
||||
|
||||
Attributes responseAttributes =
|
||||
Attributes.builder()
|
||||
.put(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200)
|
||||
.put(HttpAttributes.HTTP_REQUEST_BODY_SIZE, 100)
|
||||
.put(HttpAttributes.HTTP_RESPONSE_BODY_SIZE, 200)
|
||||
.put(NetworkAttributes.NETWORK_PROTOCOL_NAME, "http")
|
||||
.put(NetworkAttributes.NETWORK_PROTOCOL_VERSION, "2.0")
|
||||
.put(NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4")
|
||||
.put(NetworkAttributes.SERVER_SOCKET_DOMAIN, "somehost20")
|
||||
.put(NetworkAttributes.SERVER_SOCKET_PORT, 8080)
|
||||
.build();
|
||||
|
||||
Context parent =
|
||||
Context.root()
|
||||
.with(
|
||||
Span.wrap(
|
||||
SpanContext.create(
|
||||
"ff01020304050600ff0a0b0c0d0e0f00",
|
||||
"090a0b0c0d0e0f00",
|
||||
TraceFlags.getSampled(),
|
||||
TraceState.getDefault())));
|
||||
|
||||
Context context1 = listener.onStart(parent, requestAttributes, nanos(100));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics()).isEmpty();
|
||||
|
||||
Context context2 = listener.onStart(Context.root(), requestAttributes, nanos(150));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics()).isEmpty();
|
||||
|
||||
listener.onEnd(context1, responseAttributes, nanos(250));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(100 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(NetworkAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(NetworkAttributes.SERVER_PORT, 1234),
|
||||
equalTo(
|
||||
NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(200 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(NetworkAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(NetworkAttributes.SERVER_PORT, 1234),
|
||||
equalTo(
|
||||
NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))));
|
||||
|
||||
listener.onEnd(context2, responseAttributes, nanos(300));
|
||||
|
||||
assertThat(metricReader.collectAllMetrics())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(200 /* bytes */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(400 /* bytes */))));
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
return TimeUnit.MILLISECONDS.toNanos(millis);
|
||||
}
|
||||
}
|
||||
|
|
@ -106,59 +106,7 @@ class HttpClientMetricsStableSemconvTest {
|
|||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00"))
|
||||
.hasBucketBoundaries(DURATION_BUCKETS))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(100 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(NetworkAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(NetworkAttributes.SERVER_PORT, 1234),
|
||||
equalTo(
|
||||
NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasUnit("By")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point ->
|
||||
point
|
||||
.hasSum(200 /* bytes */)
|
||||
.hasAttributesSatisfying(
|
||||
equalTo(HttpAttributes.HTTP_REQUEST_METHOD, "GET"),
|
||||
equalTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, 200),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_NAME, "http"),
|
||||
equalTo(
|
||||
NetworkAttributes.NETWORK_PROTOCOL_VERSION, "2.0"),
|
||||
equalTo(NetworkAttributes.SERVER_ADDRESS, "localhost"),
|
||||
equalTo(NetworkAttributes.SERVER_PORT, 1234),
|
||||
equalTo(
|
||||
NetworkAttributes.SERVER_SOCKET_ADDRESS, "1.2.3.4"))
|
||||
.hasExemplarsSatisfying(
|
||||
exemplar ->
|
||||
exemplar
|
||||
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
|
||||
.hasSpanId("090a0b0c0d0e0f00")))));
|
||||
.hasBucketBoundaries(DURATION_BUCKETS))));
|
||||
|
||||
listener.onEnd(context2, responseAttributes, nanos(300));
|
||||
|
||||
|
|
@ -170,19 +118,7 @@ class HttpClientMetricsStableSemconvTest {
|
|||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(
|
||||
point -> point.hasSum(0.3 /* seconds */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.request.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(200 /* bytes */))),
|
||||
metric ->
|
||||
assertThat(metric)
|
||||
.hasName("http.client.response.size")
|
||||
.hasHistogramSatisfying(
|
||||
histogram ->
|
||||
histogram.hasPointsSatisfying(point -> point.hasSum(400 /* bytes */))));
|
||||
point -> point.hasSum(0.3 /* seconds */))));
|
||||
}
|
||||
|
||||
private static long nanos(int millis) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ import akka.http.scaladsl.model.HttpRequest;
|
|||
import akka.http.scaladsl.model.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -27,7 +29,7 @@ public class AkkaHttpClientSingletons {
|
|||
SETTER = new HttpHeaderSetter(GlobalOpenTelemetry.getPropagators());
|
||||
AkkaHttpClientAttributesGetter httpAttributesGetter = new AkkaHttpClientAttributesGetter();
|
||||
AkkaHttpNetAttributesGetter netAttributesGetter = new AkkaHttpNetAttributesGetter();
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpRequest, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
AkkaHttpUtil.instrumentationName(),
|
||||
|
|
@ -42,8 +44,11 @@ public class AkkaHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpasyncclient;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -26,7 +28,7 @@ public final class ApacheHttpAsyncClientSingletons {
|
|||
ApacheHttpAsyncClientNetAttributesGetter netAttributesGetter =
|
||||
new ApacheHttpAsyncClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<ApacheHttpClientRequest, HttpResponse> builder =
|
||||
Instrumenter.<ApacheHttpClientRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -41,8 +43,11 @@ public final class ApacheHttpAsyncClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<ApacheHttpClientRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpclient.v2_0;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -26,7 +28,7 @@ public final class ApacheHttpClientSingletons {
|
|||
ApacheHttpClientNetAttributesGetter netAttributesGetter =
|
||||
new ApacheHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpMethod, HttpMethod> builder =
|
||||
Instrumenter.<HttpMethod, HttpMethod>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -41,8 +43,11 @@ public final class ApacheHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpMethod, HttpMethod> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpclient.v4_0;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -26,7 +28,7 @@ public final class ApacheHttpClientSingletons {
|
|||
ApacheHttpClientNetAttributesGetter netAttributesGetter =
|
||||
new ApacheHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<ApacheHttpClientRequest, HttpResponse> builder =
|
||||
Instrumenter.<ApacheHttpClientRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -41,8 +43,11 @@ public final class ApacheHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<ApacheHttpClientRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -34,6 +36,7 @@ public final class ApacheHttpClientTelemetryBuilder {
|
|||
HttpClientAttributesExtractor.builder(
|
||||
ApacheHttpClientHttpAttributesGetter.INSTANCE,
|
||||
new ApacheHttpClientNetAttributesGetter());
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
ApacheHttpClientTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -92,6 +95,19 @@ public final class ApacheHttpClientTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public ApacheHttpClientTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link ApacheHttpClientTelemetry} configured with this {@link
|
||||
* ApacheHttpClientTelemetryBuilder}.
|
||||
|
|
@ -100,7 +116,7 @@ public final class ApacheHttpClientTelemetryBuilder {
|
|||
ApacheHttpClientHttpAttributesGetter httpAttributesGetter =
|
||||
ApacheHttpClientHttpAttributesGetter.INSTANCE;
|
||||
|
||||
Instrumenter<ApacheHttpClientRequest, HttpResponse> instrumenter =
|
||||
InstrumenterBuilder<ApacheHttpClientRequest, HttpResponse> builder =
|
||||
Instrumenter.<ApacheHttpClientRequest, HttpResponse>builder(
|
||||
openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -108,7 +124,13 @@ public final class ApacheHttpClientTelemetryBuilder {
|
|||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
Instrumenter<ApacheHttpClientRequest, HttpResponse> instrumenter =
|
||||
builder
|
||||
// We manually inject because we need to inject internal requests for redirects.
|
||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.apachehttpclient.v5_0;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -27,7 +29,7 @@ public final class ApacheHttpClientSingletons {
|
|||
ApacheHttpClientNetAttributesGetter netAttributesGetter =
|
||||
new ApacheHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpRequest, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -42,8 +44,11 @@ public final class ApacheHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ public final class ArmeriaSingletons {
|
|||
PeerServiceAttributesExtractor.create(
|
||||
new ArmeriaNetClientAttributesGetter(),
|
||||
CommonConfig.get().getPeerServiceMapping()))
|
||||
.setEmitExperimentalHttpClientMetrics(
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics())
|
||||
.build();
|
||||
|
||||
CLIENT_DECORATOR = telemetry.newClientDecorator();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
|
||||
|
|
@ -39,6 +40,7 @@ public final class ArmeriaTelemetryBuilder {
|
|||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
@Nullable private String peerService;
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
private final List<AttributesExtractor<? super RequestContext, ? super RequestLog>>
|
||||
additionalExtractors = new ArrayList<>();
|
||||
|
|
@ -168,6 +170,19 @@ public final class ArmeriaTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public ArmeriaTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArmeriaTelemetry build() {
|
||||
ArmeriaHttpClientAttributesGetter clientAttributesGetter =
|
||||
ArmeriaHttpClientAttributesGetter.INSTANCE;
|
||||
|
|
@ -207,6 +222,9 @@ public final class ArmeriaTelemetryBuilder {
|
|||
clientInstrumenterBuilder.addAttributesExtractor(
|
||||
AttributesExtractor.constant(SemanticAttributes.PEER_SERVICE, peerService));
|
||||
}
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
clientInstrumenterBuilder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
return new ArmeriaTelemetry(
|
||||
clientInstrumenterBuilder.buildClientInstrumenter(ClientRequestContextSetter.INSTANCE),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import com.ning.http.client.Request;
|
|||
import com.ning.http.client.Response;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -27,7 +29,7 @@ public final class AsyncHttpClientSingletons {
|
|||
AsyncHttpClientNetAttributesGetter netAttributesGetter =
|
||||
new AsyncHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<Request, Response> builder =
|
||||
Instrumenter.<Request, Response>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -42,8 +44,11 @@ public final class AsyncHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<Request, Response> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -26,7 +28,7 @@ public final class AsyncHttpClientSingletons {
|
|||
AsyncHttpClientNetAttributesGetter netAttributeGetter =
|
||||
new AsyncHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<RequestContext, Response> builder =
|
||||
Instrumenter.<RequestContext, Response>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -42,8 +44,11 @@ public final class AsyncHttpClientSingletons {
|
|||
PeerServiceAttributesExtractor.create(
|
||||
netAttributeGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addAttributesExtractor(new AsyncHttpClientAdditionalAttributesExtractor())
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<RequestContext, Response> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import com.google.api.client.http.HttpRequest;
|
|||
import com.google.api.client.http.HttpResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -27,7 +29,7 @@ public class GoogleHttpClientSingletons {
|
|||
GoogleHttpClientNetAttributesGetter netAttributesGetter =
|
||||
new GoogleHttpClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpRequest, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -42,8 +44,11 @@ public class GoogleHttpClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.httpurlconnection;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -23,7 +25,7 @@ public final class HttpUrlConnectionSingletons {
|
|||
HttpUrlHttpAttributesGetter httpAttributesGetter = new HttpUrlHttpAttributesGetter();
|
||||
HttpUrlNetAttributesGetter netAttributesGetter = new HttpUrlNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpURLConnection, Integer> builder =
|
||||
Instrumenter.<HttpURLConnection, Integer>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.http-url-connection",
|
||||
|
|
@ -42,8 +44,11 @@ public final class HttpUrlConnectionSingletons {
|
|||
.addContextCustomizer(
|
||||
(context, httpRequestPacket, startAttributes) ->
|
||||
GetOutputStreamContext.init(context))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(RequestPropertySetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(RequestPropertySetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpURLConnection, Integer> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ public class JavaHttpClientSingletons {
|
|||
CommonConfig.get().getKnownHttpRequestMethods(),
|
||||
singletonList(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping())));
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping())),
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics());
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpRequest, HttpResponse<?>> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public final class JavaHttpClientTelemetryBuilder {
|
|||
private List<String> capturedRequestHeaders = emptyList();
|
||||
private List<String> capturedResponseHeaders = emptyList();
|
||||
@Nullable private Set<String> knownMethods = null;
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
JavaHttpClientTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -88,6 +89,19 @@ public final class JavaHttpClientTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public JavaHttpClientTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaHttpClientTelemetry build() {
|
||||
Instrumenter<HttpRequest, HttpResponse<?>> instrumenter =
|
||||
JavaHttpClientInstrumenterFactory.createInstrumenter(
|
||||
|
|
@ -95,7 +109,8 @@ public final class JavaHttpClientTelemetryBuilder {
|
|||
capturedRequestHeaders,
|
||||
capturedResponseHeaders,
|
||||
knownMethods,
|
||||
additionalExtractors);
|
||||
additionalExtractors,
|
||||
emitExperimentalHttpClientMetrics);
|
||||
|
||||
return new JavaHttpClientTelemetry(
|
||||
instrumenter, new HttpHeadersSetter(openTelemetry.getPropagators()));
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ package io.opentelemetry.instrumentation.httpclient.internal;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -32,8 +34,9 @@ public final class JavaHttpClientInstrumenterFactory {
|
|||
List<String> capturedRequestHeaders,
|
||||
List<String> capturedResponseHeaders,
|
||||
@Nullable Set<String> knownMethods,
|
||||
List<AttributesExtractor<? super HttpRequest, ? super HttpResponse<?>>>
|
||||
additionalExtractors) {
|
||||
List<AttributesExtractor<? super HttpRequest, ? super HttpResponse<?>>> additionalExtractors,
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
|
||||
JavaHttpClientAttributesGetter httpAttributesGetter = JavaHttpClientAttributesGetter.INSTANCE;
|
||||
|
||||
HttpClientAttributesExtractorBuilder<HttpRequest, HttpResponse<?>>
|
||||
|
|
@ -46,13 +49,19 @@ public final class JavaHttpClientInstrumenterFactory {
|
|||
httpAttributesExtractorBuilder.setKnownMethods(knownMethods);
|
||||
}
|
||||
|
||||
return Instrumenter.<HttpRequest, HttpResponse<?>>builder(
|
||||
openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
InstrumenterBuilder<HttpRequest, HttpResponse<?>> builder =
|
||||
Instrumenter.<HttpRequest, HttpResponse<?>>builder(
|
||||
openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
return builder.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
|
||||
private JavaHttpClientInstrumenterFactory() {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import com.sun.jersey.api.client.ClientRequest;
|
|||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -25,7 +27,7 @@ public class JaxRsClientSingletons {
|
|||
JaxRsClientHttpAttributesGetter httpAttributesGetter = new JaxRsClientHttpAttributesGetter();
|
||||
JaxRsClientNetAttributesGetter netAttributesGetter = new JaxRsClientNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<ClientRequest, ClientResponse> builder =
|
||||
Instrumenter.<ClientRequest, ClientResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -40,8 +42,11 @@ public class JaxRsClientSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(ClientRequestHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(ClientRequestHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<ClientRequest, ClientResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ public class JettyHttpClientSingletons {
|
|||
.setCapturedRequestHeaders(CommonConfig.get().getClientRequestHeaders())
|
||||
.setCapturedResponseHeaders(CommonConfig.get().getClientResponseHeaders())
|
||||
.setKnownMethods(CommonConfig.get().getKnownHttpRequestMethods())
|
||||
.setEmitExperimentalHttpClientMetrics(
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics())
|
||||
.build();
|
||||
|
||||
public static Instrumenter<Request, Response> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,19 @@ public final class JettyClientTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public JettyClientTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
instrumenterBuilder.setEmitExperimentalHttpClientMetrics(emitExperimentalHttpClientMetrics);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JettyClientTelemetry} with the settings of this {@link
|
||||
* JettyClientTelemetryBuilder}.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -36,6 +38,7 @@ public final class JettyClientInstrumenterBuilder {
|
|||
httpAttributesExtractorBuilder =
|
||||
HttpClientAttributesExtractor.builder(
|
||||
JettyClientHttpAttributesGetter.INSTANCE, new JettyHttpClientNetAttributesGetter());
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
public JettyClientInstrumenterBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -66,17 +69,29 @@ public final class JettyClientInstrumenterBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public JettyClientInstrumenterBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Instrumenter<Request, Response> build() {
|
||||
JettyClientHttpAttributesGetter httpAttributesGetter = JettyClientHttpAttributesGetter.INSTANCE;
|
||||
|
||||
return Instrumenter.<Request, Response>builder(
|
||||
this.openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
InstrumenterBuilder<Request, Response> builder =
|
||||
Instrumenter.<Request, Response>builder(
|
||||
this.openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
return builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.joddhttp.v4_2;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -25,7 +27,7 @@ public final class JoddHttpSingletons {
|
|||
JoddHttpHttpAttributesGetter httpAttributesGetter = new JoddHttpHttpAttributesGetter();
|
||||
JoddHttpNetAttributesGetter netAttributesGetter = new JoddHttpNetAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpRequest, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequest, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -40,8 +42,11 @@ public final class JoddHttpSingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public static Instrumenter<HttpRequest, HttpResponse> instrumenter() {
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@
|
|||
package io.opentelemetry.instrumentation.ktor.v2_0.client
|
||||
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.client.statement.*
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor
|
||||
|
|
@ -25,6 +26,7 @@ class KtorClientTracingBuilder {
|
|||
KtorHttpClientAttributesGetter,
|
||||
KtorNetClientAttributesGetter,
|
||||
)
|
||||
private var emitExperimentalHttpClientMetrics = false
|
||||
|
||||
fun setOpenTelemetry(openTelemetry: OpenTelemetry) {
|
||||
this.openTelemetry = openTelemetry
|
||||
|
|
@ -55,6 +57,17 @@ class KtorClientTracingBuilder {
|
|||
additionalExtractors += extractors
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics `true` if the experimental HTTP client metrics are to be emitted.
|
||||
*/
|
||||
fun setEmitExperimentalHttpClientMetrics(
|
||||
emitExperimentalHttpClientMetrics: Boolean
|
||||
) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics
|
||||
}
|
||||
|
||||
internal fun build(): KtorClientTracing {
|
||||
val initializedOpenTelemetry = openTelemetry
|
||||
?: throw IllegalArgumentException("OpenTelemetry must be set")
|
||||
|
|
@ -64,12 +77,16 @@ class KtorClientTracingBuilder {
|
|||
INSTRUMENTATION_NAME,
|
||||
HttpSpanNameExtractor.create(KtorHttpClientAttributesGetter),
|
||||
)
|
||||
|
||||
val instrumenter = instrumenterBuilder
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(KtorHttpClientAttributesGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
instrumenterBuilder.addOperationMetrics(HttpClientExperimentalMetrics.get())
|
||||
}
|
||||
|
||||
val instrumenter = instrumenterBuilder
|
||||
.buildInstrumenter(alwaysClient())
|
||||
|
||||
return KtorClientTracing(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ package io.opentelemetry.javaagent.instrumentation.netty.v3_8.client;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -31,7 +33,7 @@ public final class NettyClientSingletons {
|
|||
NettyHttpClientAttributesGetter httpAttributesGetter = new NettyHttpClientAttributesGetter();
|
||||
NettyNetClientAttributesGetter netAttributesGetter = new NettyNetClientAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpRequestAndChannel, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -48,8 +50,11 @@ public final class NettyClientSingletons {
|
|||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.addContextCustomizer(
|
||||
(context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context))
|
||||
.buildClientInstrumenter(HttpRequestHeadersSetter.INSTANCE);
|
||||
(context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context));
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildClientInstrumenter(HttpRequestHeadersSetter.INSTANCE);
|
||||
|
||||
NettyConnectNetAttributesGetter nettyConnectAttributesGetter =
|
||||
new NettyConnectNetAttributesGetter();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -37,18 +38,21 @@ public final class NettyClientInstrumenterFactory {
|
|||
private final boolean connectionTelemetryEnabled;
|
||||
private final boolean sslTelemetryEnabled;
|
||||
private final Map<String, String> peerServiceMapping;
|
||||
private final boolean emitExperimentalHttpClientMetrics;
|
||||
|
||||
public NettyClientInstrumenterFactory(
|
||||
OpenTelemetry openTelemetry,
|
||||
String instrumentationName,
|
||||
boolean connectionTelemetryEnabled,
|
||||
boolean sslTelemetryEnabled,
|
||||
Map<String, String> peerServiceMapping) {
|
||||
Map<String, String> peerServiceMapping,
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
this.instrumentationName = instrumentationName;
|
||||
this.connectionTelemetryEnabled = connectionTelemetryEnabled;
|
||||
this.sslTelemetryEnabled = sslTelemetryEnabled;
|
||||
this.peerServiceMapping = peerServiceMapping;
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
}
|
||||
|
||||
public Instrumenter<HttpRequestAndChannel, HttpResponse> createHttpInstrumenter(
|
||||
|
|
@ -68,15 +72,21 @@ public final class NettyClientInstrumenterFactory {
|
|||
extractorBuilder.setKnownMethods(knownMethods);
|
||||
}
|
||||
|
||||
return Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
|
||||
openTelemetry, instrumentationName, HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(extractorBuilder.build())
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(netAttributesGetter, peerServiceMapping))
|
||||
.addAttributesExtractors(additionalHttpAttributeExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpRequestHeadersSetter.INSTANCE);
|
||||
InstrumenterBuilder<HttpRequestAndChannel, HttpResponse> builder =
|
||||
Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
|
||||
openTelemetry,
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(extractorBuilder.build())
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(netAttributesGetter, peerServiceMapping))
|
||||
.addAttributesExtractors(additionalHttpAttributeExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
return builder.buildClientInstrumenter(HttpRequestHeadersSetter.INSTANCE);
|
||||
}
|
||||
|
||||
public NettyConnectionInstrumenter createConnectionInstrumenter() {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ public final class NettyClientSingletons {
|
|||
"io.opentelemetry.netty-4.0",
|
||||
connectionTelemetryEnabled,
|
||||
sslTelemetryEnabled,
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
CommonConfig.get().getPeerServiceMapping(),
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics());
|
||||
INSTRUMENTER =
|
||||
factory.createHttpInstrumenter(
|
||||
CommonConfig.get().getClientRequestHeaders(),
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ public final class NettyClientSingletons {
|
|||
"io.opentelemetry.netty-4.1",
|
||||
connectionTelemetryEnabled,
|
||||
sslTelemetryEnabled,
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
CommonConfig.get().getPeerServiceMapping(),
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics());
|
||||
INSTRUMENTER =
|
||||
factory.createHttpInstrumenter(
|
||||
CommonConfig.get().getClientRequestHeaders(),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public final class NettyClientTelemetryBuilder {
|
|||
private Set<String> knownMethods = null;
|
||||
private final List<AttributesExtractor<HttpRequestAndChannel, HttpResponse>>
|
||||
additionalAttributesExtractors = new ArrayList<>();
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
NettyClientTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -85,11 +86,29 @@ public final class NettyClientTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public NettyClientTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns a new {@link NettyClientTelemetry} with the given configuration. */
|
||||
public NettyClientTelemetry build() {
|
||||
return new NettyClientTelemetry(
|
||||
new NettyClientInstrumenterFactory(
|
||||
openTelemetry, "io.opentelemetry.netty-4.1", false, false, Collections.emptyMap())
|
||||
openTelemetry,
|
||||
"io.opentelemetry.netty-4.1",
|
||||
false,
|
||||
false,
|
||||
Collections.emptyMap(),
|
||||
emitExperimentalHttpClientMetrics)
|
||||
.createHttpInstrumenter(
|
||||
capturedRequestHeaders,
|
||||
capturedResponseHeaders,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ import com.squareup.okhttp.Response;
|
|||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -32,7 +34,7 @@ public final class OkHttp2Singletons {
|
|||
|
||||
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<Request, Response> builder =
|
||||
Instrumenter.<Request, Response>builder(
|
||||
openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -47,8 +49,11 @@ public final class OkHttp2Singletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildInstrumenter(alwaysClient());
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER = builder.buildInstrumenter(alwaysClient());
|
||||
|
||||
TRACING_INTERCEPTOR = new TracingInterceptor(INSTRUMENTER, openTelemetry.getPropagators());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ public final class OkHttp3Singletons {
|
|||
CommonConfig.get().getClientRequestHeaders(),
|
||||
CommonConfig.get().getClientResponseHeaders(),
|
||||
CommonConfig.get().getKnownHttpRequestMethods(),
|
||||
emptyList());
|
||||
emptyList(),
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics());
|
||||
|
||||
public static final Interceptor CONTEXT_INTERCEPTOR =
|
||||
chain -> {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public final class OkHttpTelemetryBuilder {
|
|||
private List<String> capturedRequestHeaders = emptyList();
|
||||
private List<String> capturedResponseHeaders = emptyList();
|
||||
@Nullable private Set<String> knownMethods = null;
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
OkHttpTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -85,6 +86,19 @@ public final class OkHttpTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public OkHttpTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link OkHttpTelemetry} with the settings of this {@link OkHttpTelemetryBuilder}.
|
||||
*/
|
||||
|
|
@ -95,7 +109,8 @@ public final class OkHttpTelemetryBuilder {
|
|||
capturedRequestHeaders,
|
||||
capturedResponseHeaders,
|
||||
knownMethods,
|
||||
additionalExtractors),
|
||||
additionalExtractors,
|
||||
emitExperimentalHttpClientMetrics),
|
||||
openTelemetry.getPropagators());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtracto
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -34,7 +36,8 @@ public final class OkHttpInstrumenterFactory {
|
|||
List<String> capturedRequestHeaders,
|
||||
List<String> capturedResponseHeaders,
|
||||
@Nullable Set<String> knownMethods,
|
||||
List<AttributesExtractor<Request, Response>> additionalAttributesExtractors) {
|
||||
List<AttributesExtractor<Request, Response>> additionalAttributesExtractors,
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
|
||||
OkHttpAttributesGetter httpAttributesGetter = OkHttpAttributesGetter.INSTANCE;
|
||||
OkHttpNetAttributesGetter netAttributesGetter = OkHttpNetAttributesGetter.INSTANCE;
|
||||
|
|
@ -47,13 +50,20 @@ public final class OkHttpInstrumenterFactory {
|
|||
extractorBuilder.setKnownMethods(knownMethods);
|
||||
}
|
||||
|
||||
return Instrumenter.<Request, Response>builder(
|
||||
openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(extractorBuilder.build())
|
||||
.addAttributesExtractors(additionalAttributesExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildInstrumenter(alwaysClient());
|
||||
InstrumenterBuilder<Request, Response> builder =
|
||||
Instrumenter.<Request, Response>builder(
|
||||
openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(extractorBuilder.build())
|
||||
.addAttributesExtractors(additionalAttributesExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
return builder.buildInstrumenter(alwaysClient());
|
||||
}
|
||||
|
||||
private OkHttpInstrumenterFactory() {}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.playws;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -22,22 +24,26 @@ public final class PlayWsClientInstrumenterFactory {
|
|||
PlayWsClientHttpAttributesGetter httpAttributesGetter = new PlayWsClientHttpAttributesGetter();
|
||||
PlayWsClientNetAttributesGetter netAttributesGetter = new PlayWsClientNetAttributesGetter();
|
||||
|
||||
return Instrumenter.<Request, Response>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
HttpClientAttributesExtractor.builder(httpAttributesGetter, netAttributesGetter)
|
||||
.setCapturedRequestHeaders(CommonConfig.get().getClientRequestHeaders())
|
||||
.setCapturedResponseHeaders(CommonConfig.get().getClientResponseHeaders())
|
||||
.setKnownMethods(CommonConfig.get().getKnownHttpRequestMethods())
|
||||
.build())
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
InstrumenterBuilder<Request, Response> builder =
|
||||
Instrumenter.<Request, Response>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpAttributesGetter))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
|
||||
.addAttributesExtractor(
|
||||
HttpClientAttributesExtractor.builder(httpAttributesGetter, netAttributesGetter)
|
||||
.setCapturedRequestHeaders(CommonConfig.get().getClientRequestHeaders())
|
||||
.setCapturedResponseHeaders(CommonConfig.get().getClientResponseHeaders())
|
||||
.setKnownMethods(CommonConfig.get().getKnownHttpRequestMethods())
|
||||
.build())
|
||||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
return builder.buildClientInstrumenter(HttpHeaderSetter.INSTANCE);
|
||||
}
|
||||
|
||||
private PlayWsClientInstrumenterFactory() {}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ package io.opentelemetry.javaagent.instrumentation.reactornetty.v1_0;
|
|||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -46,7 +48,7 @@ public final class ReactorNettySingletons {
|
|||
ReactorNettyNetClientAttributesGetter netAttributesGetter =
|
||||
new ReactorNettyNetClientAttributesGetter();
|
||||
|
||||
INSTRUMENTER =
|
||||
InstrumenterBuilder<HttpClientConfig, HttpClientResponse> builder =
|
||||
Instrumenter.<HttpClientConfig, HttpClientResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -61,7 +63,12 @@ public final class ReactorNettySingletons {
|
|||
.addAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
INSTRUMENTER =
|
||||
builder
|
||||
// headers are injected in ResponseReceiverInstrumenter
|
||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
|
||||
|
|
@ -71,7 +78,8 @@ public final class ReactorNettySingletons {
|
|||
INSTRUMENTATION_NAME,
|
||||
connectionTelemetryEnabled,
|
||||
false,
|
||||
CommonConfig.get().getPeerServiceMapping());
|
||||
CommonConfig.get().getPeerServiceMapping(),
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics());
|
||||
CONNECTION_INSTRUMENTER = instrumenterFactory.createConnectionInstrumenter();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -31,6 +33,7 @@ public final class SpringWebTelemetryBuilder {
|
|||
httpAttributesExtractorBuilder =
|
||||
HttpClientAttributesExtractor.builder(
|
||||
SpringWebHttpAttributesGetter.INSTANCE, new SpringWebNetAttributesGetter());
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
SpringWebTelemetryBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -88,6 +91,19 @@ public final class SpringWebTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public SpringWebTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link SpringWebTelemetry} with the settings of this {@link
|
||||
* SpringWebTelemetryBuilder}.
|
||||
|
|
@ -95,7 +111,7 @@ public final class SpringWebTelemetryBuilder {
|
|||
public SpringWebTelemetry build() {
|
||||
SpringWebHttpAttributesGetter httpAttributeGetter = SpringWebHttpAttributesGetter.INSTANCE;
|
||||
|
||||
Instrumenter<HttpRequest, ClientHttpResponse> instrumenter =
|
||||
InstrumenterBuilder<HttpRequest, ClientHttpResponse> builder =
|
||||
Instrumenter.<HttpRequest, ClientHttpResponse>builder(
|
||||
openTelemetry,
|
||||
INSTRUMENTATION_NAME,
|
||||
|
|
@ -103,9 +119,13 @@ public final class SpringWebTelemetryBuilder {
|
|||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributeGetter))
|
||||
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
|
||||
.addAttributesExtractors(additionalExtractors)
|
||||
.addOperationMetrics(HttpClientMetrics.get())
|
||||
.buildClientInstrumenter(HttpRequestSetter.INSTANCE);
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
Instrumenter<HttpRequest, ClientHttpResponse> instrumenter =
|
||||
builder.buildClientInstrumenter(HttpRequestSetter.INSTANCE);
|
||||
return new SpringWebTelemetry(instrumenter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public final class WebClientHelper {
|
|||
new SpringWebfluxTelemetryClientBuilder(GlobalOpenTelemetry.get())
|
||||
.setCapturedClientRequestHeaders(CommonConfig.get().getClientRequestHeaders())
|
||||
.setCapturedClientResponseHeaders(CommonConfig.get().getClientResponseHeaders())
|
||||
.setKnownMethods(CommonConfig.get().getKnownHttpRequestMethods())
|
||||
.addClientAttributesExtractor(
|
||||
PeerServiceAttributesExtractor.create(
|
||||
new WebClientNetAttributesGetter(), CommonConfig.get().getPeerServiceMapping()))
|
||||
|
|
@ -31,6 +32,8 @@ public final class WebClientHelper {
|
|||
InstrumentationConfig.get()
|
||||
.getBoolean(
|
||||
"otel.instrumentation.spring-webflux.experimental-span-attributes", false))
|
||||
.setEmitExperimentalHttpClientMetrics(
|
||||
CommonConfig.get().shouldEmitExperimentalHttpClientMetrics())
|
||||
.build();
|
||||
|
||||
public static void addFilter(List<ExchangeFilterFunction> exchangeFilterFunctions) {
|
||||
|
|
|
|||
|
|
@ -150,6 +150,19 @@ public final class SpringWebfluxTelemetryBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the instrumentation to emit experimental HTTP client metrics.
|
||||
*
|
||||
* @param emitExperimentalHttpClientMetrics {@code true} if the experimental HTTP client metrics
|
||||
* are to be emitted.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public SpringWebfluxTelemetryBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
clientBuilder.setEmitExperimentalHttpClientMetrics(emitExperimentalHttpClientMetrics);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link SpringWebfluxTelemetry} with the settings of this {@link
|
||||
* SpringWebfluxTelemetryBuilder}.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -42,6 +43,7 @@ public final class SpringWebfluxTelemetryClientBuilder {
|
|||
WebClientHttpAttributesGetter.INSTANCE, new WebClientNetAttributesGetter());
|
||||
|
||||
private boolean captureExperimentalSpanAttributes = false;
|
||||
private boolean emitExperimentalHttpClientMetrics = false;
|
||||
|
||||
public SpringWebfluxTelemetryClientBuilder(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
|
|
@ -100,6 +102,13 @@ public final class SpringWebfluxTelemetryClientBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public SpringWebfluxTelemetryClientBuilder setEmitExperimentalHttpClientMetrics(
|
||||
boolean emitExperimentalHttpClientMetrics) {
|
||||
this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link SpringWebfluxTelemetry} with the settings of this {@link
|
||||
* SpringWebfluxTelemetryClientBuilder}.
|
||||
|
|
@ -121,6 +130,9 @@ public final class SpringWebfluxTelemetryClientBuilder {
|
|||
if (captureExperimentalSpanAttributes) {
|
||||
clientBuilder.addAttributesExtractor(new WebClientExperimentalAttributesExtractor());
|
||||
}
|
||||
if (emitExperimentalHttpClientMetrics) {
|
||||
clientBuilder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
// headers are injected elsewhere; ClientRequest is immutable
|
||||
return clientBuilder.buildInstrumenter(alwaysClient());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
|
|||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientExperimentalMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||
|
|
@ -41,6 +42,9 @@ public final class VertxClientInstrumenterFactory {
|
|||
PeerServiceAttributesExtractor.create(
|
||||
netAttributesGetter, CommonConfig.get().getPeerServiceMapping()))
|
||||
.addOperationMetrics(HttpClientMetrics.get());
|
||||
if (CommonConfig.get().shouldEmitExperimentalHttpClientMetrics()) {
|
||||
builder.addOperationMetrics(HttpClientExperimentalMetrics.get());
|
||||
}
|
||||
|
||||
return builder.buildClientInstrumenter(new HttpRequestHeaderSetter());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ public final class CommonConfig {
|
|||
private final List<String> serverResponseHeaders;
|
||||
private final Set<String> knownHttpRequestMethods;
|
||||
private final boolean statementSanitizationEnabled;
|
||||
private final boolean emitExperimentalHttpClientMetrics;
|
||||
|
||||
CommonConfig(InstrumentationConfig config) {
|
||||
peerServiceMapping =
|
||||
|
|
@ -66,6 +67,8 @@ public final class CommonConfig {
|
|||
new ArrayList<>(HttpConstants.KNOWN_METHODS)));
|
||||
statementSanitizationEnabled =
|
||||
config.getBoolean("otel.instrumentation.common.db-statement-sanitizer.enabled", true);
|
||||
emitExperimentalHttpClientMetrics =
|
||||
config.getBoolean("otel.instrumentation.http.client.emit-experimental-metrics", false);
|
||||
}
|
||||
|
||||
public Map<String, String> getPeerServiceMapping() {
|
||||
|
|
@ -95,4 +98,8 @@ public final class CommonConfig {
|
|||
public boolean isStatementSanitizationEnabled() {
|
||||
return statementSanitizationEnabled;
|
||||
}
|
||||
|
||||
public boolean shouldEmitExperimentalHttpClientMetrics() {
|
||||
return emitExperimentalHttpClientMetrics;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue