diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index cfc96d1459..0066b13fe5 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -2278,9 +2278,8 @@ libraries: attributes: [] elasticsearch: - name: elasticsearch-api-client-7.16 - description: This instrumentation enables client spans for Elasticsearch API client - requests for version 7 of the client. Versions 8.10 and later have native support - for OpenTelemetry. + description: | + This instrumentation extends the elasticsearch-rest-7.0 instrumentation by adding additional `db.elasticsearch.path_parts.id` and `db.elasticsearch.path_parts.index` attributes to Elasticsearch CLIENT spans. Versions 8.10 and later of the client have native support for OpenTelemetry. source_path: instrumentation/elasticsearch/elasticsearch-api-client-7.16 scope: name: io.opentelemetry.elasticsearch-api-client-7.16 @@ -2288,8 +2287,64 @@ libraries: javaagent: - co.elastic.clients:elasticsearch-java:[7.16,7.17.20) - co.elastic.clients:elasticsearch-java:[8.0.0,8.10) + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - name: db.elasticsearch.path_parts.id + type: STRING + - name: db.elasticsearch.path_parts.index + type: STRING + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: http.request.method + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING + - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: db.elasticsearch.path_parts.id + type: STRING + - name: db.elasticsearch.path_parts.index + type: STRING + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING + - name: http.request.method + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING - name: elasticsearch-rest-5.0 - description: This instrumentation enables tracing for Elasticsearch REST clients. + description: This instrumentation enables database CLIENT spans and metrics for + Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-5.0 scope: name: io.opentelemetry.elasticsearch-rest-5.0 @@ -2300,10 +2355,14 @@ libraries: configurations: - name: otel.instrumentation.elasticsearch.capture-search-query description: | - Enable the capture of search query bodies. It is important to note that Elasticsearch queries - may contain personal or sensitive information. + Enable the capture of search query bodies. It is important to note that Elasticsearch queries may contain personal or sensitive information. 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 telemetry: - when: default spans: @@ -2319,8 +2378,35 @@ libraries: type: LONG - name: url.full type: STRING + - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.system.name + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: db.system.name + type: STRING + - name: http.request.method + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING - name: elasticsearch-rest-6.4 - description: This instrumentation enables tracing for Elasticsearch REST clients. + description: This instrumentation enables database CLIENT spans and metrics for + Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-6.4 scope: name: io.opentelemetry.elasticsearch-rest-6.4 @@ -2333,6 +2419,11 @@ libraries: Enable the capture of search query bodies. It is important to note that Elasticsearch queries may contain personal or sensitive information. 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 telemetry: - when: default spans: @@ -2348,8 +2439,35 @@ libraries: type: LONG - name: url.full type: STRING + - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.system.name + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: db.system.name + type: STRING + - name: http.request.method + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING - name: elasticsearch-rest-7.0 - description: This instrumentation enables tracing for Elasticsearch REST clients. + description: This instrumentation enables database CLIENT spans and metrics for + Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-7.0 scope: name: io.opentelemetry.elasticsearch-rest-7.0 @@ -2364,6 +2482,11 @@ libraries: Enable the capture of search query bodies. It is important to note that Elasticsearch queries may contain personal or sensitive information. 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 telemetry: - when: default spans: @@ -2379,9 +2502,35 @@ libraries: type: LONG - name: url.full type: STRING + - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.system.name + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + spans: + - span_kind: CLIENT + attributes: + - name: db.system.name + type: STRING + - name: http.request.method + type: STRING + - name: server.address + type: STRING + - name: server.port + type: LONG + - name: url.full + type: STRING - name: elasticsearch-transport-5.0 description: | - This instrumentation enables client spans for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. source_path: instrumentation/elasticsearch/elasticsearch-transport-5.0 scope: name: io.opentelemetry.elasticsearch-transport-5.0 @@ -2391,9 +2540,15 @@ libraries: - org.elasticsearch:elasticsearch:[5.0.0,5.3.0) configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: | + Enable the capture of the experimental span attributes `elasticsearch.action`, `elasticsearch.id`, `elasticsearch.request`, `elasticsearch.request.indices`, `elasticsearch.request.write.routing`, `elasticsearch.request.write.type`, `elasticsearch.response.status`, `elasticsearch.shard.replication.failed`, `elasticsearch.shard.replication.successful`, `elasticsearch.shard.replication.total`, `elasticsearch.type`, and `elasticsearch.version`. 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 telemetry: - when: default spans: @@ -2442,6 +2597,16 @@ libraries: - name: network.peer.port type: LONG - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING spans: - span_kind: CLIENT attributes: @@ -2457,7 +2622,7 @@ libraries: type: LONG - name: elasticsearch-transport-5.3 description: | - This instrumentation enables client spans for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. source_path: instrumentation/elasticsearch/elasticsearch-transport-5.3 scope: name: io.opentelemetry.elasticsearch-transport-5.3 @@ -2467,7 +2632,8 @@ libraries: - org.elasticsearch:elasticsearch:[5.3.0,6.0.0) configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: | + Enable the capture of `elasticsearch.action`, `elasticsearch.id`, `elasticsearch.request`, `elasticsearch.request.indices`, `elasticsearch.request.search.types`, `elasticsearch.request.write.type`, `elasticsearch.request.write.version`, `elasticsearch.response.status`, `elasticsearch.shard.broadcast.failed`, `elasticsearch.shard.broadcast.successful`, `elasticsearch.shard.broadcast.total`, `elasticsearch.shard.replication.failed`, `elasticsearch.shard.replication.successful`, `elasticsearch.shard.replication.total`, `elasticsearch.type`, and `elasticsearch.version` experimental span attributes. type: boolean default: false telemetry: @@ -2528,6 +2694,16 @@ libraries: - name: network.peer.port type: LONG - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING spans: - span_kind: CLIENT attributes: @@ -2543,7 +2719,7 @@ libraries: type: LONG - name: elasticsearch-transport-6.0 description: | - This instrumentation enables client spans for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. Each call produces a span named after the Elasticsearch action, enriched with transport-specific attributes. source_path: instrumentation/elasticsearch/elasticsearch-transport-6.0 scope: name: io.opentelemetry.elasticsearch-transport-6.0 @@ -2553,7 +2729,8 @@ libraries: - org.elasticsearch.client:transport:[6.0.0,) configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: | + Enable the capture of `elasticsearch.action`, `elasticsearch.id`, `elasticsearch.request`, `elasticsearch.request.indices`, `elasticsearch.request.write.type`, `elasticsearch.request.write.version`, `elasticsearch.response.status`, `elasticsearch.shard.replication.failed`, `elasticsearch.shard.replication.successful`, `elasticsearch.shard.replication.total`, `elasticsearch.type`, and `elasticsearch.version` experimental span attributes. type: boolean default: false telemetry: @@ -2610,6 +2787,16 @@ libraries: - name: network.type type: STRING - when: otel.semconv-stability.opt-in=database + metrics: + - name: db.client.operation.duration + description: Duration of database client operations. + type: HISTOGRAM + unit: s + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING spans: - span_kind: CLIENT attributes: diff --git a/instrumentation-docs/instrumentations.sh b/instrumentation-docs/instrumentations.sh index 884aa9aa0b..79d186871e 100755 --- a/instrumentation-docs/instrumentations.sh +++ b/instrumentation-docs/instrumentations.sh @@ -67,6 +67,7 @@ readonly INSTRUMENTATIONS=( "elasticsearch:elasticsearch-api-client-7.16:javaagent:test" "elasticsearch:elasticsearch-api-client-7.16:javaagent:testStableSemconv" "elasticsearch:elasticsearch-rest-7.0:javaagent:test" + "elasticsearch:elasticsearch-rest-7.0:javaagent:testStableSemconv" "elasticsearch:elasticsearch-transport-5.0:javaagent:test" "elasticsearch:elasticsearch-transport-5.0:javaagent:testStableSemconv" "elasticsearch:elasticsearch-transport-5.0:javaagent:testExperimental" @@ -139,7 +140,9 @@ readonly INSTRUMENTATIONS=( readonly COLIMA_INSTRUMENTATIONS=( "spring:spring-jms:spring-jms-6.0:javaagent:test" "elasticsearch:elasticsearch-rest-6.4:javaagent:test" + "elasticsearch:elasticsearch-rest-6.4:javaagent:testStableSemconv" "elasticsearch:elasticsearch-rest-5.0:javaagent:test" + "elasticsearch:elasticsearch-rest-5.0:javaagent:testStableSemconv" "oracle-ucp-11.2:javaagent:test" "oracle-ucp-11.2:javaagent:testStableSemconv" ) diff --git a/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/TelemetryParser.java b/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/TelemetryParser.java index 1c561717b5..c5aaf69343 100644 --- a/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/TelemetryParser.java +++ b/instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/TelemetryParser.java @@ -16,7 +16,10 @@ class TelemetryParser { // armeria-grpc uses grpc-1.6 instrumenter. "io.opentelemetry.armeria-grpc-1.14", Set.of("io.opentelemetry.grpc-1.6"), // couchbase-2.6 extends couchbase-2.0 instrumentation with more attributes. - "io.opentelemetry.couchbase-2.6", Set.of("io.opentelemetry.couchbase-2.0")); + "io.opentelemetry.couchbase-2.6", Set.of("io.opentelemetry.couchbase-2.0"), + // elasticsearch-rest-7.0 extends elasticsearch-api-client-7.16 with more attributes. + "io.opentelemetry.elasticsearch-api-client-7.16", + Set.of("io.opentelemetry.elasticsearch-rest-7.0")); /** * Checks if the given telemetry scope is valid for the specified module scope. diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchClientTest.java b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchClientTest.java index f883419aa4..284c41a820 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchClientTest.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.apiclient; import static io.opentelemetry.instrumentation.testing.GlobalTraceUtil.runWithSpan; +import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -16,7 +17,9 @@ import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; import static io.opentelemetry.semconv.UrlAttributes.URL_FULL; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_ELASTICSEARCH_PATH_PARTS; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION_NAME; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM_NAME; import static org.assertj.core.api.Assertions.assertThat; import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient; @@ -154,6 +157,14 @@ class ElasticsearchClientTest { URL_FULL, httpHost.toURI() + "/test-index/_doc/test-id?timeout=10s"), equalTo(HTTP_RESPONSE_STATUS_CODE, 201L)))); + + assertDurationMetric( + testing, + "io.opentelemetry.elasticsearch-rest-7.0", + DB_OPERATION_NAME, + DB_SYSTEM_NAME, + SERVER_ADDRESS, + SERVER_PORT); } @Test diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml index 3dc6d3cf9d..fc2be4a9be 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml @@ -1,2 +1,5 @@ -description: This instrumentation enables client spans for Elasticsearch API client requests for - version 7 of the client. Versions 8.10 and later have native support for OpenTelemetry. +description: > + This instrumentation extends the elasticsearch-rest-7.0 instrumentation by adding + additional `db.elasticsearch.path_parts.id` and `db.elasticsearch.path_parts.index` attributes to + Elasticsearch CLIENT spans. Versions 8.10 and later of the client have native support for + OpenTelemetry. diff --git a/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts index 122908d82e..b0b0af1321 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts @@ -42,4 +42,13 @@ tasks { systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") } + + val testStableSemconv by registering(Test::class) { + jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=database") + } + + check { + dependsOn(testStableSemconv) + } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v5_0/ElasticsearchRest5Test.java b/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v5_0/ElasticsearchRest5Test.java index fc0b9313f7..9617787c38 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v5_0/ElasticsearchRest5Test.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v5_0/ElasticsearchRest5Test.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v5_0; +import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -14,6 +15,7 @@ import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; import static io.opentelemetry.semconv.UrlAttributes.URL_FULL; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM_NAME; import static org.assertj.core.api.Assertions.assertThat; import com.fasterxml.jackson.databind.ObjectMapper; @@ -115,6 +117,13 @@ class ElasticsearchRest5Test { equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health"), equalTo(HTTP_RESPONSE_STATUS_CODE, 200)))); + + assertDurationMetric( + testing, + "io.opentelemetry.elasticsearch-rest-5.0", + DB_SYSTEM_NAME, + SERVER_ADDRESS, + SERVER_PORT); } @Test diff --git a/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml index 091cbe4861..33c6ef1213 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml @@ -1,8 +1,14 @@ -description: This instrumentation enables tracing for Elasticsearch REST clients. +description: This instrumentation enables database CLIENT spans and metrics for Elasticsearch REST clients. configurations: - name: otel.instrumentation.elasticsearch.capture-search-query - description: | + description: > Enable the capture of search query bodies. It is important to note that Elasticsearch queries may contain personal or sensitive information. 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" diff --git a/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts index 2fdeea1a6e..1e53d35d09 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts @@ -36,9 +36,17 @@ dependencies { } tasks { - test { + withType().configureEach { usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) - systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") } + + val testStableSemconv by registering(Test::class) { + jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=database") + } + + check { + dependsOn(testStableSemconv) + } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v6_4/ElasticsearchRest6Test.java b/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v6_4/ElasticsearchRest6Test.java index f9c4f82913..35ba08f6d1 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v6_4/ElasticsearchRest6Test.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v6_4/ElasticsearchRest6Test.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v6_4; +import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -14,6 +15,7 @@ import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; import static io.opentelemetry.semconv.UrlAttributes.URL_FULL; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM_NAME; import static org.assertj.core.api.Assertions.assertThat; import com.fasterxml.jackson.databind.ObjectMapper; @@ -82,30 +84,36 @@ class ElasticsearchRest6Test { assertThat(result.get("status")).isEqualTo("green"); testing.waitAndAssertTraces( - trace -> { - trace.hasSpansSatisfyingExactly( - span -> - span.hasName("GET") - .hasKind(SpanKind.CLIENT) - .hasNoParent() - .hasAttributesSatisfyingExactly( - equalTo(maybeStable(DB_SYSTEM), "elasticsearch"), - equalTo(HTTP_REQUEST_METHOD, "GET"), - equalTo(SERVER_ADDRESS, httpHost.getHostName()), - equalTo(SERVER_PORT, httpHost.getPort()), - equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health")), - span -> - span.hasName("GET") - .hasKind(SpanKind.CLIENT) - .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo(SERVER_ADDRESS, httpHost.getHostName()), - equalTo(SERVER_PORT, httpHost.getPort()), - equalTo(HTTP_REQUEST_METHOD, "GET"), - equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), - equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health"), - equalTo(HTTP_RESPONSE_STATUS_CODE, 200L))); - }); + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasName("GET") + .hasKind(SpanKind.CLIENT) + .hasNoParent() + .hasAttributesSatisfyingExactly( + equalTo(maybeStable(DB_SYSTEM), "elasticsearch"), + equalTo(HTTP_REQUEST_METHOD, "GET"), + equalTo(SERVER_ADDRESS, httpHost.getHostName()), + equalTo(SERVER_PORT, httpHost.getPort()), + equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health")), + span -> + span.hasName("GET") + .hasKind(SpanKind.CLIENT) + .hasParent(trace.getSpan(0)) + .hasAttributesSatisfyingExactly( + equalTo(SERVER_ADDRESS, httpHost.getHostName()), + equalTo(SERVER_PORT, httpHost.getPort()), + equalTo(HTTP_REQUEST_METHOD, "GET"), + equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), + equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health"), + equalTo(HTTP_RESPONSE_STATUS_CODE, 200L)))); + + assertDurationMetric( + testing, + "io.opentelemetry.elasticsearch-rest-6.4", + DB_SYSTEM_NAME, + SERVER_ADDRESS, + SERVER_PORT); } @Test @@ -138,10 +146,7 @@ class ElasticsearchRest6Test { } }; testing.runWithSpan( - "parent", - () -> { - client.performRequestAsync("GET", "_cluster/health", responseListener); - }); + "parent", () -> client.performRequestAsync("GET", "_cluster/health", responseListener)); countDownLatch.await(); if (exception[0] != null) { diff --git a/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml index 224089a16b..33c6ef1213 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml @@ -1,4 +1,4 @@ -description: This instrumentation enables tracing for Elasticsearch REST clients. +description: This instrumentation enables database CLIENT spans and metrics for Elasticsearch REST clients. configurations: - name: otel.instrumentation.elasticsearch.capture-search-query description: > @@ -6,3 +6,9 @@ configurations: may contain personal or sensitive information. 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" diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts index 5076b34c32..992f5c71e5 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts @@ -39,9 +39,19 @@ dependencies { } tasks { - test { + withType().configureEach { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") } + + val testStableSemconv by registering(Test::class) { + jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metadataConfig", "otel.semconv-stability.opt-in=database") + } + + check { + dependsOn(testStableSemconv) + } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7Test.java b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7Test.java index bde1b70f7d..42d0dc1485 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7Test.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7Test.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.v7_0; import static io.opentelemetry.instrumentation.testing.GlobalTraceUtil.runWithSpan; +import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; @@ -15,6 +16,7 @@ import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS; import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT; import static io.opentelemetry.semconv.UrlAttributes.URL_FULL; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM_NAME; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.trace.SpanKind; @@ -106,6 +108,13 @@ class ElasticsearchRest7Test { equalTo(NETWORK_PROTOCOL_VERSION, "1.1"), equalTo(URL_FULL, httpHost.toURI() + "/_cluster/health"), equalTo(HTTP_RESPONSE_STATUS_CODE, 200L)))); + + assertDurationMetric( + testing, + "io.opentelemetry.elasticsearch-rest-7.0", + DB_SYSTEM_NAME, + SERVER_ADDRESS, + SERVER_PORT); } @Test diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml index 224089a16b..33c6ef1213 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml @@ -1,4 +1,4 @@ -description: This instrumentation enables tracing for Elasticsearch REST clients. +description: This instrumentation enables database CLIENT spans and metrics for Elasticsearch REST clients. configurations: - name: otel.instrumentation.elasticsearch.capture-search-query description: > @@ -6,3 +6,9 @@ configurations: may contain personal or sensitive information. 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" diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5NodeClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5NodeClientTest.java index 0bd700ef23..e24c6efc67 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5NodeClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_0/Elasticsearch5NodeClientTest.java @@ -19,6 +19,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer; import org.elasticsearch.transport.Netty3Plugin; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,4 +83,9 @@ class Elasticsearch5NodeClientTest extends AbstractElasticsearchNodeClientTest { protected boolean hasWriteVersion() { return false; } + + @Test + void testDurationMetric() throws Exception { + metricAssertion("io.opentelemetry.elasticsearch-transport-5.0"); + } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml index c327ced42d..35a7824df3 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml @@ -1,8 +1,21 @@ description: > - This instrumentation enables client spans for Elasticsearch transport client requests. Each call - produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. + Each call produces a span named after the Elasticsearch action, enriched with transport-specific + attributes. configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: > + Enable the capture of the experimental span attributes `elasticsearch.action`, + `elasticsearch.id`, `elasticsearch.request`, `elasticsearch.request.indices`, + `elasticsearch.request.write.routing`, `elasticsearch.request.write.type`, + `elasticsearch.response.status`, `elasticsearch.shard.replication.failed`, + `elasticsearch.shard.replication.successful`, `elasticsearch.shard.replication.total`, + `elasticsearch.type`, and `elasticsearch.version`. 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" diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53NodeClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53NodeClientTest.java index 13eafa5b4d..ae51755351 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53NodeClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/Elasticsearch53NodeClientTest.java @@ -20,6 +20,7 @@ import org.elasticsearch.node.Node; import org.elasticsearch.transport.Netty3Plugin; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -89,4 +90,9 @@ class Elasticsearch53NodeClientTest extends AbstractElasticsearchNodeClientTest public Client client() { return client; } + + @Test + void testDurationMetric() throws Exception { + metricAssertion("io.opentelemetry.elasticsearch-transport-5.3"); + } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml index c327ced42d..f9a9e1711e 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml @@ -1,8 +1,17 @@ description: > - This instrumentation enables client spans for Elasticsearch transport client requests. Each call - produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. + Each call produces a span named after the Elasticsearch action, enriched with transport-specific + attributes. configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: > + Enable the capture of `elasticsearch.action`, `elasticsearch.id`, `elasticsearch.request`, + `elasticsearch.request.indices`, `elasticsearch.request.search.types`, + `elasticsearch.request.write.type`, `elasticsearch.request.write.version`, + `elasticsearch.response.status`, `elasticsearch.shard.broadcast.failed`, + `elasticsearch.shard.broadcast.successful`, `elasticsearch.shard.broadcast.total`, + `elasticsearch.shard.replication.failed`, `elasticsearch.shard.replication.successful`, + `elasticsearch.shard.replication.total`, `elasticsearch.type`, and + `elasticsearch.version` experimental span attributes. type: boolean default: false diff --git a/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml index c327ced42d..859a19c123 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml @@ -1,8 +1,15 @@ description: > - This instrumentation enables client spans for Elasticsearch transport client requests. Each call - produces a span named after the Elasticsearch action, enriched with transport-specific attributes. + This instrumentation enables CLIENT spans and metrics for Elasticsearch transport client requests. + Each call produces a span named after the Elasticsearch action, enriched with transport-specific + attributes. configurations: - name: otel.instrumentation.elasticsearch.experimental-span-attributes - description: Enable the capture of experimental span attributes. + description: > + Enable the capture of `elasticsearch.action`, `elasticsearch.id`, `elasticsearch.request`, + `elasticsearch.request.indices`, `elasticsearch.request.write.type`, + `elasticsearch.request.write.version`, `elasticsearch.response.status`, + `elasticsearch.shard.replication.failed`, `elasticsearch.shard.replication.successful`, + `elasticsearch.shard.replication.total`, `elasticsearch.type`, and + `elasticsearch.version` experimental span attributes. type: boolean default: false diff --git a/instrumentation/elasticsearch/elasticsearch-transport-6.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/AbstractElasticsearch6NodeClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-6.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/AbstractElasticsearch6NodeClientTest.java index 614ed4c663..e00fd3d105 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-6.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/AbstractElasticsearch6NodeClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-6.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v6_0/AbstractElasticsearch6NodeClientTest.java @@ -17,6 +17,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.Node; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,4 +99,9 @@ public abstract class AbstractElasticsearch6NodeClientTest .execute() .actionGet(TIMEOUT); } + + @Test + void testDurationMetric() throws Exception { + metricAssertion("io.opentelemetry.elasticsearch-transport-6.0"); + } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchNodeClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchNodeClientTest.java index 5988fd9fd9..14c15485a9 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchNodeClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchNodeClientTest.java @@ -7,8 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport; import static io.opentelemetry.api.common.AttributeKey.longKey; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.instrumentation.testing.junit.db.DbClientMetricsTestUtil.assertDurationMetric; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; +import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME; import static io.opentelemetry.semconv.ErrorAttributes.ERROR_TYPE; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; @@ -276,4 +279,14 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti protected boolean hasWriteVersion() { return true; } + + protected void metricAssertion(String instrumentationName) throws Exception { + ClusterHealthStatus clusterHealthStatus = + testing.runWithSpan("parent", this::clusterHealthSync); + + assertThat(clusterHealthStatus.name()).isEqualTo("GREEN"); + testing.waitForTraces(1); + + assertDurationMetric(testing, instrumentationName, DB_SYSTEM_NAME, DB_OPERATION_NAME); + } }