diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index e78ac4009a86..c26a929d6547 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -7229,12 +7229,122 @@ libraries: - io.ktor:ktor-client-core:3.0.0 kubernetes: - name: kubernetes-client-7.0 + display_name: Kubernetes Client + description: This instrumentation enables HTTP client spans and HTTP client metrics + for the Kubernetes Client for Java. + semantic_conventions: + - HTTP_CLIENT_SPANS + - HTTP_CLIENT_METRICS + library_link: https://github.com/kubernetes-client/java source_path: instrumentation/kubernetes-client-7.0 scope: name: io.opentelemetry.kubernetes-client-7.0 + schema_url: https://opentelemetry.io/schemas/1.37.0 target_versions: javaagent: - io.kubernetes:client-java-api:[7.0.0,) + configurations: + - name: otel.instrumentation.kubernetes-client.experimental-span-attributes + description: | + Enables experimental span attributes `kubernetes-client.namespace` and `kubernetes-client.name` for Kubernetes API requests. + type: boolean + default: false + - name: otel.instrumentation.http.known-methods + description: | + Configures the instrumentation to recognize an alternative set of HTTP request methods. All other methods will be treated as `_OTHER`. + type: list + default: CONNECT,DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,TRACE + - name: otel.instrumentation.http.client.capture-request-headers + description: List of HTTP request headers to capture in HTTP client telemetry. + type: list + default: '' + - name: otel.instrumentation.http.client.capture-response-headers + description: List of HTTP response headers to capture in HTTP client telemetry. + type: list + default: '' + - name: otel.instrumentation.common.peer-service-mapping + description: Used to specify a mapping from host names or IP addresses to peer + services. + type: map + default: '' + - name: otel.instrumentation.http.client.emit-experimental-telemetry + description: | + Enable the capture of experimental HTTP client telemetry. Adds the `http.request.body.size` and `http.response.body.size` attributes to spans, and records `http.client.request.size` and `http.client.response.size` metrics. + type: boolean + default: false + - name: otel.instrumentation.http.client.experimental.redact-query-parameters + description: Redact sensitive URL parameters. See https://opentelemetry.io/docs/specs/semconv/http/http-spans. + type: boolean + default: true + telemetry: + - when: default + metrics: + - name: http.client.request.duration + description: Duration of HTTP client requests. + type: HISTOGRAM + unit: s + attributes: + - name: http.request.method + type: STRING + - name: http.response.status_code + type: LONG + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: error.type + type: STRING + - name: http.request.method + type: STRING + - name: http.response.status_code + type: LONG + - name: peer.service + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING + - when: otel.instrumentation.kubernetes-client.experimental-span-attributes=true + metrics: + - name: http.client.request.duration + description: Duration of HTTP client requests. + type: HISTOGRAM + unit: s + attributes: + - name: http.request.method + type: STRING + - name: http.response.status_code + type: LONG + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: error.type + type: STRING + - name: http.request.method + type: STRING + - name: http.response.status_code + type: LONG + - name: kubernetes-client.name + type: STRING + - name: kubernetes-client.namespace + type: STRING + - name: peer.service + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING lettuce: - name: lettuce-4.0 source_path: instrumentation/lettuce/lettuce-4.0 diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md index 50a71271473b..2479eb4dc1a1 100644 --- a/docs/supported-libraries.md +++ b/docs/supported-libraries.md @@ -96,13 +96,13 @@ These are the supported libraries and frameworks: | [JBoss Log Manager](https://github.com/jboss-logging/jboss-logmanager) | 1.1+ | N/A | none | | [JDBC](https://docs.oracle.com/javase/8/docs/api/java/sql/package-summary.html) | Java 8+ | [opentelemetry-jdbc](../instrumentation/jdbc/library) | [Database Client Spans], [Database Client Metrics] [6] | | [Jedis](https://github.com/xetorthio/jedis) | 1.4+ | N/A | [Database Client Spans], [Database Client Metrics] [6] | -| [JFinal](https://github.com/jfinal/jfinal) | 3.2+ | N/A | Provides `http.route` [2], Controller Spans [3] | +| [JFinal](https://github.com/jfinal/jfinal) | 3.2+ | N/A | Provides `http.route` [2], Controller Spans [3] | | [JMS](https://javaee.github.io/javaee-spec/javadocs/javax/jms/package-summary.html) | 1.1+ | N/A | [Messaging Spans] | | [Jodd Http](https://http.jodd.org/) | 4.2+ | N/A | [HTTP Client Spans], [HTTP Client Metrics] | | [JSP](https://javaee.github.io/javaee-spec/javadocs/javax/servlet/jsp/package-summary.html) | 2.3.x only | N/A | Controller Spans [3] | | [Kotlin Coroutines](https://kotlinlang.org/docs/coroutines-overview.html) | 1.0+ | N/A | Context propagation | | [Ktor](https://github.com/ktorio/ktor) | 1.0+ | [opentelemetry-ktor-1.0](../instrumentation/ktor/ktor-1.0/library),
[opentelemetry-ktor-2.0](../instrumentation/ktor/ktor-2.0/library),
[opentelemetry-ktor-3.0](../instrumentation/ktor/ktor-3.0/library) | [HTTP Client Spans], [HTTP Client Metrics], [HTTP Server Spans], [HTTP Server Metrics] | -| [Kubernetes Client](https://github.com/kubernetes-client/java) | 7.0+ | N/A | [HTTP Client Spans] | +| [Kubernetes Client](https://github.com/kubernetes-client/java) | 7.0+ | N/A | [HTTP Client Spans], [HTTP Client Metrics] | | [Lettuce](https://github.com/lettuce-io/lettuce-core) | 4.0+ | [opentelemetry-lettuce-5.1](../instrumentation/lettuce/lettuce-5.1/library) | [Database Client Spans], [Database Client Metrics] [6] | | [Log4j 1](https://logging.apache.org/log4j/1.2/) | 1.2+ | N/A | none | | [Log4j 2](https://logging.apache.org/log4j/2.x/) | 2.11+ | [opentelemetry-log4j-appender-2.17](../instrumentation/log4j/log4j-appender-2.17/library),
[opentelemetry-log4j-context-data-2.17-autoconfigure](../instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure) | none | diff --git a/instrumentation-docs/instrumentations.sh b/instrumentation-docs/instrumentations.sh index c2e1c2d0d2ea..cea6a994eeeb 100755 --- a/instrumentation-docs/instrumentations.sh +++ b/instrumentation-docs/instrumentations.sh @@ -150,6 +150,8 @@ readonly INSTRUMENTATIONS=( "jsp-2.3:javaagent:testExperimental" "kafka:kafka-clients:kafka-clients-2.6:library:test" "kafka:kafka-connect-2.6:testing:test" + "kubernetes-client-7.0:javaagent:test" + "kubernetes-client-7.0:javaagent:testExperimental" "nats:nats-2.17:javaagent:test" "nats:nats-2.17:javaagent:testExperimental" "netty:netty-3.8:javaagent:test" diff --git a/instrumentation/kubernetes-client-7.0/javaagent/build.gradle.kts b/instrumentation/kubernetes-client-7.0/javaagent/build.gradle.kts index eb53c8f01a54..657ab4ef6557 100644 --- a/instrumentation/kubernetes-client-7.0/javaagent/build.gradle.kts +++ b/instrumentation/kubernetes-client-7.0/javaagent/build.gradle.kts @@ -39,7 +39,20 @@ tasks { } } -tasks.withType().configureEach { - // TODO run tests both with and without experimental span attributes - jvmArgs("-Dotel.instrumentation.kubernetes-client.experimental-span-attributes=true") +tasks { + withType().configureEach { + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + } + + val testExperimental by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + jvmArgs("-Dotel.instrumentation.kubernetes-client.experimental-span-attributes=true") + systemProperty("metadataConfig", "otel.instrumentation.kubernetes-client.experimental-span-attributes=true") + } + + check { + dependsOn(testExperimental) + } } diff --git a/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientTest.java b/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientTest.java index 3dcdec9b92b8..033c22279f88 100644 --- a/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientTest.java +++ b/instrumentation/kubernetes-client-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientTest.java @@ -5,7 +5,9 @@ package io.opentelemetry.javaagent.instrumentation.kubernetesclient; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -20,7 +22,6 @@ import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.openapi.ApiException; import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; @@ -33,6 +34,7 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -49,6 +51,14 @@ class KubernetesClientTest { private CoreV1Api coreV1Api; + @Nullable + private static String experimental(String value) { + if (Boolean.getBoolean("otel.instrumentation.kubernetes-client.experimental-span-attributes")) { + return value; + } + return null; + } + @BeforeEach void beforeEach() { mockWebServer.start(); @@ -92,8 +102,23 @@ void synchronousCall() throws ApiException { equalTo(SERVER_PORT, mockWebServer.httpPort()), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")))); + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); + + testing.waitAndAssertMetrics( + "io.opentelemetry.kubernetes-client-7.0", + "http.client.request.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("Duration of HTTP client requests.") + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> point.hasSumGreaterThan(0.0))))); } @Test @@ -103,10 +128,7 @@ void handleErrorsInSyncCall() { ApiException exception = null; try { testing.runWithSpan( - "parent", - () -> { - coreV1Api.connectGetNamespacedPodProxy("name", "namespace", "path"); - }); + "parent", () -> coreV1Api.connectGetNamespacedPodProxy("name", "namespace", "path")); } catch (ApiException e) { exception = e; } @@ -141,8 +163,9 @@ void handleErrorsInSyncCall() { equalTo(PEER_SERVICE, "test-peer-service"), equalTo(ERROR_TYPE, "451"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")))); + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); } @Test @@ -154,21 +177,20 @@ void asynchronousCall() throws ApiException, InterruptedException { testing.runWithSpan( "parent", - () -> { - coreV1Api.connectGetNamespacedPodProxyAsync( - "name", - "namespace", - "path", - new ApiCallbackTemplate() { - @Override - public void onSuccess( - String result, int statusCode, Map> responseHeaders) { - responseBodyReference.set(result); - countDownLatch.countDown(); - testing.runWithSpan("callback", () -> {}); - } - }); - }); + () -> + coreV1Api.connectGetNamespacedPodProxyAsync( + "name", + "namespace", + "path", + new ApiCallbackTemplate() { + @Override + public void onSuccess( + String result, int statusCode, Map> responseHeaders) { + responseBodyReference.set(result); + countDownLatch.countDown(); + testing.runWithSpan("callback", () -> {}); + } + })); countDownLatch.await(); @@ -195,8 +217,9 @@ public void onSuccess( equalTo(SERVER_PORT, mockWebServer.httpPort()), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")), + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) @@ -214,21 +237,20 @@ void handleErrorsInAsynchronousCall() throws ApiException, InterruptedException testing.runWithSpan( "parent", - () -> { - coreV1Api.connectGetNamespacedPodProxyAsync( - "name", - "namespace", - "path", - new ApiCallbackTemplate() { - @Override - public void onFailure( - ApiException e, int statusCode, Map> responseHeaders) { - exceptionReference.set(e); - countDownLatch.countDown(); - testing.runWithSpan("callback", () -> {}); - } - }); - }); + () -> + coreV1Api.connectGetNamespacedPodProxyAsync( + "name", + "namespace", + "path", + new ApiCallbackTemplate() { + @Override + public void onFailure( + ApiException e, int statusCode, Map> responseHeaders) { + exceptionReference.set(e); + countDownLatch.countDown(); + testing.runWithSpan("callback", () -> {}); + } + })); countDownLatch.await(); @@ -258,8 +280,9 @@ public void onFailure( equalTo(PEER_SERVICE, "test-peer-service"), equalTo(ERROR_TYPE, "451"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")), + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) diff --git a/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientVer20Test.java b/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientVer20Test.java index 0a89e46650ea..34d47e5e6cd8 100644 --- a/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientVer20Test.java +++ b/instrumentation/kubernetes-client-7.0/javaagent/src/version20Test/java/io/opentelemetry/javaagent/instrumentation/kubernetesclient/KubernetesClientVer20Test.java @@ -5,7 +5,9 @@ package io.opentelemetry.javaagent.instrumentation.kubernetesclient; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.instrumentation.testing.util.TelemetryDataUtil.orderByRootSpanName; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -20,7 +22,6 @@ import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.openapi.ApiException; import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; @@ -33,6 +34,7 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -49,6 +51,14 @@ class KubernetesClientVer20Test { private CoreV1Api coreV1Api; + @Nullable + private static String experimental(String value) { + if (Boolean.getBoolean("otel.instrumentation.kubernetes-client.experimental-span-attributes")) { + return value; + } + return null; + } + @BeforeEach void beforeEach() { mockWebServer.start(); @@ -96,8 +106,23 @@ void synchronousCall() throws ApiException { equalTo(SERVER_PORT, mockWebServer.httpPort()), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")))); + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); + + testing.waitAndAssertMetrics( + "io.opentelemetry.kubernetes-client-7.0", + "http.client.request.duration", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("Duration of HTTP client requests.") + .hasUnit("s") + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> point.hasSumGreaterThan(0.0))))); } @Test @@ -108,9 +133,10 @@ void handleErrorsInSyncCall() { try { testing.runWithSpan( "parent", - () -> { - coreV1Api.connectGetNamespacedPodProxyWithPath("name", "namespace", "path").execute(); - }); + () -> + coreV1Api + .connectGetNamespacedPodProxyWithPath("name", "namespace", "path") + .execute()); } catch (ApiException e) { exception = e; } @@ -145,8 +171,9 @@ void handleErrorsInSyncCall() { equalTo(ERROR_TYPE, "451"), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")))); + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))))); } @Test @@ -158,20 +185,21 @@ void asynchronousCall() throws ApiException, InterruptedException { testing.runWithSpan( "parent", - () -> { - coreV1Api - .connectGetNamespacedPodProxyWithPath("name", "namespace", "path") - .executeAsync( - new ApiCallbackTemplate() { - @Override - public void onSuccess( - String result, int statusCode, Map> responseHeaders) { - responseBodyReference.set(result); - countDownLatch.countDown(); - testing.runWithSpan("callback", () -> {}); - } - }); - }); + () -> + coreV1Api + .connectGetNamespacedPodProxyWithPath("name", "namespace", "path") + .executeAsync( + new ApiCallbackTemplate() { + @Override + public void onSuccess( + String result, + int statusCode, + Map> responseHeaders) { + responseBodyReference.set(result); + countDownLatch.countDown(); + testing.runWithSpan("callback", () -> {}); + } + })); countDownLatch.await(); @@ -198,8 +226,9 @@ public void onSuccess( equalTo(SERVER_PORT, mockWebServer.httpPort()), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")), + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) @@ -217,20 +246,21 @@ void handleErrorsInAsynchronousCall() throws ApiException, InterruptedException testing.runWithSpan( "parent", - () -> { - coreV1Api - .connectGetNamespacedPodProxyWithPath("name", "namespace", "path") - .executeAsync( - new ApiCallbackTemplate() { - @Override - public void onFailure( - ApiException e, int statusCode, Map> responseHeaders) { - exceptionReference.set(e); - countDownLatch.countDown(); - testing.runWithSpan("callback", () -> {}); - } - }); - }); + () -> + coreV1Api + .connectGetNamespacedPodProxyWithPath("name", "namespace", "path") + .executeAsync( + new ApiCallbackTemplate() { + @Override + public void onFailure( + ApiException e, + int statusCode, + Map> responseHeaders) { + exceptionReference.set(e); + countDownLatch.countDown(); + testing.runWithSpan("callback", () -> {}); + } + })); countDownLatch.await(); @@ -260,8 +290,9 @@ public void onFailure( equalTo(ERROR_TYPE, "451"), equalTo(PEER_SERVICE, "test-peer-service"), equalTo( - AttributeKey.stringKey("kubernetes-client.namespace"), "namespace"), - equalTo(AttributeKey.stringKey("kubernetes-client.name"), "name")), + stringKey("kubernetes-client.namespace"), + experimental("namespace")), + equalTo(stringKey("kubernetes-client.name"), experimental("name"))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) diff --git a/instrumentation/kubernetes-client-7.0/metadata.yaml b/instrumentation/kubernetes-client-7.0/metadata.yaml new file mode 100644 index 000000000000..a6825eac17ea --- /dev/null +++ b/instrumentation/kubernetes-client-7.0/metadata.yaml @@ -0,0 +1,42 @@ +description: This instrumentation enables HTTP client spans and HTTP client metrics for the Kubernetes Client for Java. +display_name: Kubernetes Client +semantic_conventions: + - HTTP_CLIENT_SPANS + - HTTP_CLIENT_METRICS +library_link: https://github.com/kubernetes-client/java +configurations: + - name: otel.instrumentation.kubernetes-client.experimental-span-attributes + description: > + Enables experimental span attributes `kubernetes-client.namespace` and + `kubernetes-client.name` for Kubernetes API requests. + type: boolean + default: false + - name: otel.instrumentation.http.known-methods + description: > + Configures the instrumentation to recognize an alternative set of HTTP request methods. All + other methods will be treated as `_OTHER`. + type: list + default: "CONNECT,DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,TRACE" + - name: otel.instrumentation.http.client.capture-request-headers + description: List of HTTP request headers to capture in HTTP client telemetry. + type: list + default: "" + - name: otel.instrumentation.http.client.capture-response-headers + description: List of HTTP response headers to capture in HTTP client telemetry. + type: list + default: "" + - name: otel.instrumentation.common.peer-service-mapping + description: Used to specify a mapping from host names or IP addresses to peer services. + type: map + default: "" + - name: otel.instrumentation.http.client.emit-experimental-telemetry + description: > + Enable the capture of experimental HTTP client telemetry. Adds the `http.request.body.size` + and `http.response.body.size` attributes to spans, and records `http.client.request.size` and + `http.client.response.size` metrics. + type: boolean + default: false + - name: otel.instrumentation.http.client.experimental.redact-query-parameters + description: Redact sensitive URL parameters. See https://opentelemetry.io/docs/specs/semconv/http/http-spans. + type: boolean + default: true \ No newline at end of file