From 1d3f60300a5e539de51c6fb6e01b8a1cb4873b7e Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Mon, 14 Jul 2025 02:44:27 -0400 Subject: [PATCH] Elasticsearch instrumentation metadata (#14164) --- docs/instrumentation-list.yaml | 273 ++++++++++++++++++ instrumentation-docs/collect.sh | 142 ++++++--- .../javaagent/build.gradle.kts | 4 + .../metadata.yaml | 2 + .../javaagent/build.gradle.kts | 3 + .../elasticsearch-rest-5.0/metadata.yaml | 3 +- .../javaagent/build.gradle.kts | 3 + .../elasticsearch-rest-6.4/metadata.yaml | 3 +- .../javaagent/build.gradle.kts | 3 + .../elasticsearch-rest-7.0/metadata.yaml | 3 +- .../javaagent/build.gradle.kts | 12 +- .../elasticsearch-transport-5.0/metadata.yaml | 8 + .../javaagent/build.gradle.kts | 14 +- .../Elasticsearch53SpringRepositoryTest.java | 200 +++++++------ .../Elasticsearch53SpringTemplateTest.java | 140 +++++---- .../springdata/ElasticsearchSpringTest.java | 25 ++ .../elasticsearch-transport-5.3/metadata.yaml | 8 + .../javaagent/build.gradle.kts | 30 +- .../elasticsearch-transport-6.0/metadata.yaml | 8 + .../AbstractElasticsearchClientTest.java | 17 ++ .../AbstractElasticsearchNodeClientTest.java | 104 ++++--- ...tractElasticsearchTransportClientTest.java | 137 +++++---- 22 files changed, 821 insertions(+), 321 deletions(-) create mode 100644 instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml create mode 100644 instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml create mode 100644 instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/ElasticsearchSpringTest.java create mode 100644 instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml create mode 100644 instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index b7291ea049..2f0d88987b 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -1100,6 +1100,9 @@ libraries: default: false elasticsearch: - name: elasticsearch-api-client-7.16 + description: This instrumentation provides client spans for Elasticsearch API + client requests for version 7 of the client. Versions 8.10 and later have native + support for OpenTelemetry. source_path: instrumentation/elasticsearch/elasticsearch-api-client-7.16 scope: name: io.opentelemetry.elasticsearch-api-client-7.16 @@ -1108,6 +1111,7 @@ libraries: - co.elastic.clients:elasticsearch-java:[7.16,7.17.20) - co.elastic.clients:elasticsearch-java:[8.0.0,8.10) - name: elasticsearch-rest-5.0 + description: This instrumentation provides tracing for Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-5.0 scope: name: io.opentelemetry.elasticsearch-rest-5.0 @@ -1122,7 +1126,23 @@ libraries: may contain personal or sensitive information. type: boolean default: false + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - 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 - name: elasticsearch-rest-6.4 + description: This instrumentation provides tracing for Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-6.4 scope: name: io.opentelemetry.elasticsearch-rest-6.4 @@ -1135,7 +1155,23 @@ 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 + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - 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 - name: elasticsearch-rest-7.0 + description: This instrumentation provides tracing for Elasticsearch REST clients. source_path: instrumentation/elasticsearch/elasticsearch-rest-7.0 scope: name: io.opentelemetry.elasticsearch-rest-7.0 @@ -1150,7 +1186,24 @@ 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 + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - 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 - name: elasticsearch-transport-5.0 + description: | + This instrumentation provides client spans 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 @@ -1158,7 +1211,75 @@ libraries: javaagent: - org.elasticsearch.client:transport:[5.0.0,5.3.0) - 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. + type: boolean + default: false + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - when: otel.instrumentation.elasticsearch.experimental-span-attributes=true + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: elasticsearch.action + type: STRING + - name: elasticsearch.id + type: STRING + - name: elasticsearch.request + type: STRING + - name: elasticsearch.request.indices + type: STRING + - name: elasticsearch.request.write.type + type: STRING + - name: elasticsearch.response.status + type: LONG + - name: elasticsearch.shard.replication.failed + type: LONG + - name: elasticsearch.shard.replication.successful + type: LONG + - name: elasticsearch.shard.replication.total + type: LONG + - name: elasticsearch.type + type: STRING + - name: elasticsearch.version + type: LONG + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - when: otel.semconv-stability.opt-in=database + spans: + - span_kind: CLIENT + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING + - name: error.type + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG - name: elasticsearch-transport-5.3 + description: | + This instrumentation provides client spans 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 @@ -1166,7 +1287,85 @@ libraries: javaagent: - org.elasticsearch.client:transport:[5.3.0,6.0.0) - 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. + type: boolean + default: false + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - when: otel.instrumentation.elasticsearch.experimental-span-attributes=true + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: elasticsearch.action + type: STRING + - name: elasticsearch.id + type: STRING + - name: elasticsearch.request + type: STRING + - name: elasticsearch.request.indices + type: STRING + - name: elasticsearch.request.search.types + type: STRING + - name: elasticsearch.request.write.type + type: STRING + - name: elasticsearch.request.write.version + type: LONG + - name: elasticsearch.response.status + type: LONG + - name: elasticsearch.shard.broadcast.failed + type: LONG + - name: elasticsearch.shard.broadcast.successful + type: LONG + - name: elasticsearch.shard.broadcast.total + type: LONG + - name: elasticsearch.shard.replication.failed + type: LONG + - name: elasticsearch.shard.replication.successful + type: LONG + - name: elasticsearch.shard.replication.total + type: LONG + - name: elasticsearch.type + type: STRING + - name: elasticsearch.version + type: LONG + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - when: otel.semconv-stability.opt-in=database + spans: + - span_kind: CLIENT + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING + - name: error.type + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG - name: elasticsearch-transport-6.0 + description: | + This instrumentation provides client spans 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 @@ -1174,6 +1373,80 @@ libraries: javaagent: - org.elasticsearch:elasticsearch:[6.0.0,8.0.0) - org.elasticsearch.client:transport:[6.0.0,) + configurations: + - name: otel.instrumentation.elasticsearch.experimental-span-attributes + description: Enable the capture of experimental span attributes. + type: boolean + default: false + telemetry: + - when: default + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - name: network.type + type: STRING + - when: otel.instrumentation.elasticsearch.experimental-span-attributes=true + spans: + - span_kind: CLIENT + attributes: + - name: db.operation + type: STRING + - name: db.system + type: STRING + - name: elasticsearch.action + type: STRING + - name: elasticsearch.id + type: STRING + - name: elasticsearch.request + type: STRING + - name: elasticsearch.request.indices + type: STRING + - name: elasticsearch.request.write.type + type: STRING + - name: elasticsearch.request.write.version + type: LONG + - name: elasticsearch.response.status + type: LONG + - name: elasticsearch.shard.replication.failed + type: LONG + - name: elasticsearch.shard.replication.successful + type: LONG + - name: elasticsearch.shard.replication.total + type: LONG + - name: elasticsearch.type + type: STRING + - name: elasticsearch.version + type: LONG + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - name: network.type + type: STRING + - when: otel.semconv-stability.opt-in=database + spans: + - span_kind: CLIENT + attributes: + - name: db.operation.name + type: STRING + - name: db.system.name + type: STRING + - name: error.type + type: STRING + - name: network.peer.address + type: STRING + - name: network.peer.port + type: LONG + - name: network.type + type: STRING executors: - name: executors description: | diff --git a/instrumentation-docs/collect.sh b/instrumentation-docs/collect.sh index 832b3626a8..83f2c3c4ad 100755 --- a/instrumentation-docs/collect.sh +++ b/instrumentation-docs/collect.sh @@ -1,17 +1,11 @@ #!/usr/bin/env bash # Runs selected Gradle test tasks to regenerate *.telemetry output for -# individual OpenTelemetry Java agent instrumentations. +# individual OpenTelemetry Java agent instrumentations. Some instrumentation test suites don't run +# on Apple Silicon, so we use colima to run them in an x86_64 container. set -euo pipefail -# Oracle UCP won't run on Apple Silicon, so we need to use colima to run as x86_64 -if [[ "$(uname -m)" == "arm64" || "$(uname -m)" == "aarch64" ]]; then - colima start --arch x86_64 --memory 4 - export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock - export DOCKER_HOST="unix://${HOME}/.colima/docker.sock" -fi - readonly INSTRUMENTATIONS=( # : : [ gradle-task-suffix ] "activej-http-6.0:javaagent:test" @@ -66,16 +60,49 @@ readonly INSTRUMENTATIONS=( "hikaricp-3.0:javaagent:testStableSemconv" "tomcat:tomcat-jdbc:javaagent:test" "tomcat:tomcat-jdbc:javaagent:testStableSemconv" - "oracle-ucp-11.2:javaagent:test" - "oracle-ucp-11.2:javaagent:testStableSemconv" "oshi:javaagent:test" "oshi:javaagent:testExperimental" "vibur-dbcp-11.0:javaagent:test" "vibur-dbcp-11.0:javaagent:testStableSemconv" + "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-transport-5.0:javaagent:test" + "elasticsearch:elasticsearch-transport-5.0:javaagent:testStableSemconv" + "elasticsearch:elasticsearch-transport-5.0:javaagent:testExperimental" + "elasticsearch:elasticsearch-transport-5.3:javaagent:test" + "elasticsearch:elasticsearch-transport-5.3:javaagent:testStableSemconv" + "elasticsearch:elasticsearch-transport-5.3:javaagent:testExperimental" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch6Test" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch6TestStableSemconv" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch6TestExperimental" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch65Test" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch65TestStableSemconv" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch65TestExperimental" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch7Test" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch7TestStableSemconv" + "elasticsearch:elasticsearch-transport-6.0:javaagent:elasticsearch7TestExperimental" +) + +readonly COLIMA_INSTRUMENTATIONS=( + "elasticsearch:elasticsearch-rest-6.4:javaagent:test" + "elasticsearch:elasticsearch-rest-5.0:javaagent:test" + "oracle-ucp-11.2:javaagent:test" + "oracle-ucp-11.2:javaagent:testStableSemconv" ) readonly TELEMETRY_DIR_NAME=".telemetry" +# Sets up colima for x86_64 architecture if on ARM +setup_colima() { + if [[ "$(uname -m)" == "arm64" || "$(uname -m)" == "aarch64" ]]; then + echo "Setting up colima for x86_64 architecture..." + colima start --arch x86_64 --memory 4 + export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock + export DOCKER_HOST="unix://${HOME}/.colima/docker.sock" + fi +} + # Splits a single descriptor into its three logical parts. # argument $1: descriptor string (ex: "foo:bar:baz:test") # Outputs three variables via echo: @@ -144,39 +171,88 @@ build_gradle_task() { echo "$task" } +# Processes a list of descriptors and returns an array of Gradle tasks +# Args: array of descriptors +# Echoes the Gradle tasks, one per line +process_descriptors() { + local descriptors=("$@") + local -a tasks=() + + for descriptor in "${descriptors[@]}"; do + # Parse the descriptor into its components + if ! read -r module_path task_type task_suffix \ + < <(parse_descriptor "$descriptor"); then + continue # skip any badly formed descriptors + fi + + # Make sure we're starting fresh for this instrumentation + delete_existing_telemetry "$module_path" + + # Build the Gradle task string and add to array + tasks+=( "$(build_gradle_task "$module_path" "$task_type" "$task_suffix")" ) + done + + # Echo tasks, one per line + for t in "${tasks[@]}"; do + echo "$t" + done +} + +run_gradle_tasks() { + local -a tasks=("$@") + + if [[ ${#tasks[@]} -eq 0 ]]; then + echo "No tasks to run" + return 0 + fi + + echo + echo "Running Gradle tasks:" + printf ' %s\n' "${tasks[@]}" + echo + + ./gradlew "${tasks[@]}" \ + -PcollectMetadata=true \ + --rerun-tasks --continue +} + # Cleans any stray .telemetry directories left in the repo. find_and_remove_all_telemetry() { echo "Removing stray .telemetry directories..." find . -type d -name "$TELEMETRY_DIR_NAME" -exec rm -rf {} + } -# Main -declare -a gradle_tasks=() -for descriptor in "${INSTRUMENTATIONS[@]}"; do - # Parse the descriptor into its components - if ! read -r module_path task_type task_suffix \ - < <(parse_descriptor "$descriptor"); then - continue # skip any badly formed descriptors - fi +# Main execution +main() { + colima stop - # Make sure we’re starting fresh for this instrumentation - delete_existing_telemetry "$module_path" + # Process regular instrumentations + echo "Processing standard instrumentations..." + gradle_tasks=() + while IFS= read -r line; do + gradle_tasks+=("$line") + done < <(process_descriptors "${INSTRUMENTATIONS[@]}") + run_gradle_tasks "${gradle_tasks[@]}" - # Build the Gradle task string and queue it - gradle_tasks+=( "$(build_gradle_task "$module_path" "$task_type" "$task_suffix")" ) -done + # Setup colima if needed + setup_colima -echo -echo "Running Gradle tasks:" -printf ' %s\n' "${gradle_tasks[@]}" -echo + # Process colima-specific instrumentations + echo "Processing colima instrumentations..." + gradle_tasks=() + while IFS= read -r line; do + gradle_tasks+=("$line") + done < <(process_descriptors "${COLIMA_INSTRUMENTATIONS[@]}") + run_gradle_tasks "${gradle_tasks[@]}" -./gradlew "${gradle_tasks[@]}" \ - -PcollectMetadata=true \ - --rerun-tasks --continue + colima stop -# uncomment the next line to remove all .telemetry directories -#find_and_remove_all_telemetry + # uncomment the next line to remove all .telemetry directories + #find_and_remove_all_telemetry -echo "Telemetry file regeneration complete." + echo "Telemetry file regeneration complete." +} + +# Run main function +main "$@" diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/build.gradle.kts index 06ba25bd48..3603efdbf3 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/build.gradle.kts @@ -77,10 +77,14 @@ tasks { withType().configureEach { jvmArgs("-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true") usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } val testStableSemconv by registering(Test::class) { jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metaDataConfig", "otel.semconv-stability.opt-in=database") } check { diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml new file mode 100644 index 0000000000..83efc09a04 --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/metadata.yaml @@ -0,0 +1,2 @@ +description: This instrumentation provides client spans for Elasticsearch API client requests for + version 7 of the client. Versions 8.10 and later 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 f62aa7943a..0752cd75ac 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-5.0/javaagent/build.gradle.kts @@ -39,5 +39,8 @@ tasks { withType().configureEach { systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml index 65e65ca8b6..2f50a9228f 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-5.0/metadata.yaml @@ -1,7 +1,8 @@ +description: This instrumentation provides tracing for Elasticsearch REST clients. 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. type: boolean - default: false + default: false \ No newline at end of file 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 9a7139e92f..8a34194353 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-6.4/javaagent/build.gradle.kts @@ -38,5 +38,8 @@ dependencies { tasks { test { usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml index 3d330ea590..42af6c77f4 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-6.4/metadata.yaml @@ -1,7 +1,8 @@ +description: This instrumentation provides tracing for Elasticsearch REST clients. 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. type: boolean - default: false + default: false \ No newline at end of file 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 411eb46323..ba2c724151 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/build.gradle.kts @@ -41,5 +41,8 @@ dependencies { tasks { test { usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service) + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml index 3d330ea590..42af6c77f4 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/metadata.yaml @@ -1,7 +1,8 @@ +description: This instrumentation provides tracing for Elasticsearch REST clients. 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. type: boolean - default: false + default: false \ No newline at end of file diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/build.gradle.kts index dae88209c2..58eee6d204 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.0/javaagent/build.gradle.kts @@ -51,18 +51,24 @@ dependencies { tasks { withType().configureEach { - // TODO run tests both with and without experimental span attributes - jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") // required on jdk17 jvmArgs("--add-opens=java.base/java.nio=ALL-UNNAMED") jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } val testStableSemconv by registering(Test::class) { jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metaDataConfig", "otel.semconv-stability.opt-in=database") + } + + val testExperimental by registering(Test::class) { + jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") + systemProperty("metaDataConfig", "otel.instrumentation.elasticsearch.experimental-span-attributes=true") } check { - dependsOn(testStableSemconv) + dependsOn(testStableSemconv, testExperimental) } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml new file mode 100644 index 0000000000..7a02d702e3 --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.0/metadata.yaml @@ -0,0 +1,8 @@ +description: > + This instrumentation provides client spans 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. + type: boolean + default: false diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/build.gradle.kts index 22c9c83426..baf5f18321 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/build.gradle.kts @@ -69,19 +69,25 @@ tasks { withType().configureEach { systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) - // TODO run tests both with and without experimental span attributes - jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") - // required on jdk17 jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } val testStableSemconv by registering(Test::class) { jvmArgs("-Dotel.semconv-stability.opt-in=database,code") + systemProperty("metaDataConfig", "otel.semconv-stability.opt-in=database") + } + + val testExperimental by registering(Test::class) { + jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") + systemProperty("metaDataConfig", "otel.instrumentation.elasticsearch.experimental-span-attributes=true") } check { - dependsOn(testStableSemconv) + dependsOn(testStableSemconv, testExperimental) } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringRepositoryTest.java b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringRepositoryTest.java index 5bb2ac64ae..a54c73f71b 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringRepositoryTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringRepositoryTest.java @@ -13,6 +13,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.asser import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static java.util.Arrays.asList; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.internal.AutoCleanupExtension; @@ -21,6 +22,7 @@ import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.sdk.testing.assertj.AttributeAssertion; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import java.io.File; +import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; @@ -33,7 +35,7 @@ import spock.util.environment.Jvm; @SuppressWarnings("deprecation") // using deprecated semconv @TestInstance(TestInstance.Lifecycle.PER_CLASS) -class Elasticsearch53SpringRepositoryTest { +class Elasticsearch53SpringRepositoryTest extends ElasticsearchSpringTest { @RegisterExtension private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); @@ -48,7 +50,9 @@ class Elasticsearch53SpringRepositoryTest { private static DocRepository repository() { // when running on jdk 21 this test occasionally fails with timeout Assumptions.assumeTrue( - Boolean.getBoolean("testLatestDeps") || !Jvm.getCurrent().isJava21Compatible()); + Boolean.getBoolean("testLatestDeps") + || !Jvm.getCurrent().isJava21Compatible() + || Boolean.getBoolean("collectMetadata")); DocRepository result = testing.runWithSpan( @@ -91,10 +95,16 @@ class Elasticsearch53SpringRepositoryTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "SearchAction"), - equalTo(stringKey("elasticsearch.action"), "SearchAction"), - equalTo(stringKey("elasticsearch.request"), "SearchRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.request.search.types"), "doc")))); + equalTo( + stringKey("elasticsearch.action"), experimental("SearchAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("SearchRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental("test-index")), + equalTo( + stringKey("elasticsearch.request.search.types"), + experimental("doc"))))); } @Test @@ -116,35 +126,12 @@ class Elasticsearch53SpringRepositoryTest { span.hasName("IndexAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "IndexAction"), - equalTo(stringKey("elasticsearch.action"), "IndexAction"), - equalTo(stringKey("elasticsearch.request"), "IndexRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.request.write.type"), "doc"), - equalTo(longKey("elasticsearch.request.write.version"), -3), - equalTo(longKey("elasticsearch.response.status"), 201), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.total"), 2)), + .hasAttributesSatisfyingExactly(indexActionAssertions(201)), span -> span.hasName("RefreshAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "RefreshAction"), - equalTo(stringKey("elasticsearch.action"), "RefreshAction"), - equalTo(stringKey("elasticsearch.request"), "RefreshRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(longKey("elasticsearch.shard.broadcast.failed"), 0), - equalTo(longKey("elasticsearch.shard.broadcast.successful"), 5), - equalTo(longKey("elasticsearch.shard.broadcast.total"), 10)))); + .hasAttributesSatisfyingExactly(refreshActionAssertions()))); testing.clearData(); assertThat(repository.findById("1").get()).isEqualTo(doc); @@ -161,17 +148,7 @@ class Elasticsearch53SpringRepositoryTest { span.hasName("GetAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(stringKey("elasticsearch.action"), "GetAction"), - equalTo(stringKey("elasticsearch.request"), "GetRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.type"), "doc"), - equalTo(stringKey("elasticsearch.id"), "1"), - equalTo(longKey("elasticsearch.version"), 1)))); + .hasAttributesSatisfyingExactly(getActionAssertions(1)))); testing.clearData(); doc.setData("other data"); @@ -191,35 +168,12 @@ class Elasticsearch53SpringRepositoryTest { span.hasName("IndexAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "IndexAction"), - equalTo(stringKey("elasticsearch.action"), "IndexAction"), - equalTo(stringKey("elasticsearch.request"), "IndexRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.request.write.type"), "doc"), - equalTo(longKey("elasticsearch.request.write.version"), -3), - equalTo(longKey("elasticsearch.response.status"), 200), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.total"), 2)), + .hasAttributesSatisfyingExactly(indexActionAssertions(200)), span -> span.hasName("RefreshAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "RefreshAction"), - equalTo(stringKey("elasticsearch.action"), "RefreshAction"), - equalTo(stringKey("elasticsearch.request"), "RefreshRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(longKey("elasticsearch.shard.broadcast.failed"), 0), - equalTo(longKey("elasticsearch.shard.broadcast.successful"), 5), - equalTo(longKey("elasticsearch.shard.broadcast.total"), 10))), + .hasAttributesSatisfyingExactly(refreshActionAssertions())), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -231,17 +185,7 @@ class Elasticsearch53SpringRepositoryTest { span.hasName("GetAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(stringKey("elasticsearch.action"), "GetAction"), - equalTo(stringKey("elasticsearch.request"), "GetRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.type"), "doc"), - equalTo(stringKey("elasticsearch.id"), "1"), - equalTo(longKey("elasticsearch.version"), 2)))); + .hasAttributesSatisfyingExactly(getActionAssertions(2)))); testing.clearData(); repository.deleteById("1"); @@ -264,29 +208,29 @@ class Elasticsearch53SpringRepositoryTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "DeleteAction"), - equalTo(stringKey("elasticsearch.action"), "DeleteAction"), - equalTo(stringKey("elasticsearch.request"), "DeleteRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.request.write.type"), "doc"), - equalTo(longKey("elasticsearch.request.write.version"), -3), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.total"), 2)), + equalTo( + stringKey("elasticsearch.action"), experimental("DeleteAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("DeleteRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental("test-index")), + equalTo( + stringKey("elasticsearch.request.write.type"), experimental("doc")), + equalTo( + longKey("elasticsearch.request.write.version"), experimental(-3)), + equalTo( + longKey("elasticsearch.shard.replication.failed"), experimental(0)), + equalTo( + longKey("elasticsearch.shard.replication.successful"), + experimental(1)), + equalTo( + longKey("elasticsearch.shard.replication.total"), experimental(2))), span -> span.hasName("RefreshAction") .hasKind(SpanKind.CLIENT) .hasParent(trace.getSpan(0)) - .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "RefreshAction"), - equalTo(stringKey("elasticsearch.action"), "RefreshAction"), - equalTo(stringKey("elasticsearch.request"), "RefreshRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(longKey("elasticsearch.shard.broadcast.failed"), 0), - equalTo(longKey("elasticsearch.shard.broadcast.successful"), 5), - equalTo(longKey("elasticsearch.shard.broadcast.total"), 10))), + .hasAttributesSatisfyingExactly(refreshActionAssertions())), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -303,10 +247,64 @@ class Elasticsearch53SpringRepositoryTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "SearchAction"), - equalTo(stringKey("elasticsearch.action"), "SearchAction"), - equalTo(stringKey("elasticsearch.request"), "SearchRequest"), - equalTo(stringKey("elasticsearch.request.indices"), "test-index"), - equalTo(stringKey("elasticsearch.request.search.types"), "doc")))); + equalTo( + stringKey("elasticsearch.action"), experimental("SearchAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("SearchRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental("test-index")), + equalTo( + stringKey("elasticsearch.request.search.types"), + experimental("doc"))))); + } + + private static List indexActionAssertions(long status) { + return new ArrayList<>( + asList( + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "IndexAction"), + equalTo(stringKey("elasticsearch.action"), experimental("IndexAction")), + equalTo(stringKey("elasticsearch.request"), experimental("IndexRequest")), + equalTo(stringKey("elasticsearch.request.indices"), experimental("test-index")), + equalTo(stringKey("elasticsearch.request.write.type"), experimental("doc")), + equalTo(longKey("elasticsearch.request.write.version"), experimental(-3)), + equalTo(longKey("elasticsearch.response.status"), experimental(status)), + equalTo(longKey("elasticsearch.shard.replication.failed"), experimental(0)), + equalTo(longKey("elasticsearch.shard.replication.successful"), experimental(1)), + equalTo(longKey("elasticsearch.shard.replication.total"), experimental(2)))); + } + + private static List refreshActionAssertions() { + return new ArrayList<>( + asList( + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "RefreshAction"), + equalTo(stringKey("elasticsearch.action"), experimental("RefreshAction")), + equalTo(stringKey("elasticsearch.request"), experimental("RefreshRequest")), + equalTo(stringKey("elasticsearch.request.indices"), experimental("test-index")), + equalTo(longKey("elasticsearch.shard.broadcast.failed"), experimental(0)), + equalTo(longKey("elasticsearch.shard.broadcast.successful"), experimental(5)), + equalTo(longKey("elasticsearch.shard.broadcast.total"), experimental(10)))); + } + + private static List getActionAssertions(long version) { + return new ArrayList<>( + asList( + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "GetAction"), + equalTo(stringKey("elasticsearch.action"), experimental("GetAction")), + equalTo(stringKey("elasticsearch.request"), experimental("GetRequest")), + equalTo(stringKey("elasticsearch.request.indices"), experimental("test-index")), + equalTo(stringKey("elasticsearch.type"), experimental("doc")), + equalTo(stringKey("elasticsearch.id"), experimental("1")), + equalTo(longKey("elasticsearch.version"), experimental(version)))); } private static List assertFunctionName(String methodName) { diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringTemplateTest.java b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringTemplateTest.java index 222744f9f4..0cfefbd2a4 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringTemplateTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/Elasticsearch53SpringTemplateTest.java @@ -12,6 +12,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equal 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; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.awaitility.Awaitility.await; @@ -28,7 +29,6 @@ import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import java.io.File; import java.time.Duration; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -69,7 +69,7 @@ import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; import spock.util.environment.Jvm; @SuppressWarnings("deprecation") // using deprecated semconv -class Elasticsearch53SpringTemplateTest { +class Elasticsearch53SpringTemplateTest extends ElasticsearchSpringTest { private static final Logger logger = LoggerFactory.getLogger(Elasticsearch53SpringTemplateTest.class); @@ -157,7 +157,9 @@ class Elasticsearch53SpringTemplateTest { void prepareTest() { // when running on jdk 21 this test occasionally fails with timeout Assumptions.assumeTrue( - Boolean.getBoolean("testLatestDeps") || !Jvm.getCurrent().isJava21Compatible()); + Boolean.getBoolean("testLatestDeps") + || !Jvm.getCurrent().isJava21Compatible() + || Boolean.getBoolean("collectMetadata")); } @Test @@ -166,17 +168,7 @@ class Elasticsearch53SpringTemplateTest { assertThatThrownBy(() -> template.refresh(indexName)) .isInstanceOf(IndexNotFoundException.class); - List assertions = - new ArrayList<>( - Arrays.asList( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "RefreshAction"), - equalTo(stringKey("elasticsearch.action"), "RefreshAction"), - equalTo(stringKey("elasticsearch.request"), "RefreshRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName))); - + List assertions = refreshActionAttributes(indexName); if (SemconvStability.emitStableDatabaseSemconv()) { assertions.add(equalTo(ERROR_TYPE, "org.elasticsearch.index.IndexNotFoundException")); } @@ -244,9 +236,15 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "CreateIndexAction"), - equalTo(stringKey("elasticsearch.action"), "CreateIndexAction"), - equalTo(stringKey("elasticsearch.request"), "CreateIndexRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName))), + equalTo( + stringKey("elasticsearch.action"), + experimental("CreateIndexAction")), + equalTo( + stringKey("elasticsearch.request"), + experimental("CreateIndexRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental(indexName)))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -258,8 +256,12 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "ClusterHealthAction"), - equalTo(stringKey("elasticsearch.action"), "ClusterHealthAction"), - equalTo(stringKey("elasticsearch.request"), "ClusterHealthRequest"))), + equalTo( + stringKey("elasticsearch.action"), + experimental("ClusterHealthAction")), + equalTo( + stringKey("elasticsearch.request"), + experimental("ClusterHealthRequest")))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -271,10 +273,16 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "SearchAction"), - equalTo(stringKey("elasticsearch.action"), "SearchAction"), - equalTo(stringKey("elasticsearch.request"), "SearchRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName), - equalTo(stringKey("elasticsearch.request.search.types"), indexType))), + equalTo( + stringKey("elasticsearch.action"), experimental("SearchAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("SearchRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental(indexName)), + equalTo( + stringKey("elasticsearch.request.search.types"), + experimental(indexType)))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -286,15 +294,26 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "IndexAction"), - equalTo(stringKey("elasticsearch.action"), "IndexAction"), - equalTo(stringKey("elasticsearch.request"), "IndexRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName), - equalTo(stringKey("elasticsearch.request.write.type"), indexType), - equalTo(longKey("elasticsearch.request.write.version"), -3), - equalTo(longKey("elasticsearch.response.status"), 201), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.total"), 2))), + equalTo(stringKey("elasticsearch.action"), experimental("IndexAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("IndexRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental(indexName)), + equalTo( + stringKey("elasticsearch.request.write.type"), + experimental(indexType)), + equalTo( + longKey("elasticsearch.request.write.version"), experimental(-3)), + equalTo(longKey("elasticsearch.response.status"), experimental(201)), + equalTo( + longKey("elasticsearch.shard.replication.failed"), experimental(0)), + equalTo( + longKey("elasticsearch.shard.replication.successful"), + experimental(1)), + equalTo( + longKey("elasticsearch.shard.replication.total"), + experimental(2)))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -302,16 +321,7 @@ class Elasticsearch53SpringTemplateTest { .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "RefreshAction"), - equalTo(stringKey("elasticsearch.action"), "RefreshAction"), - equalTo(stringKey("elasticsearch.request"), "RefreshRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName), - equalTo(longKey("elasticsearch.shard.broadcast.failed"), 0), - equalTo(longKey("elasticsearch.shard.broadcast.successful"), 5), - equalTo(longKey("elasticsearch.shard.broadcast.total"), 10))), + refreshBroadcastActionAttributes(indexName))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -323,10 +333,38 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "SearchAction"), - equalTo(stringKey("elasticsearch.action"), "SearchAction"), - equalTo(stringKey("elasticsearch.request"), "SearchRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName), - equalTo(stringKey("elasticsearch.request.search.types"), indexType)))); + equalTo( + stringKey("elasticsearch.action"), experimental("SearchAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("SearchRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental(indexName)), + equalTo( + stringKey("elasticsearch.request.search.types"), + experimental(indexType))))); + } + + private static List refreshActionAttributes(String indexName) { + return new ArrayList<>( + asList( + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "RefreshAction"), + equalTo(stringKey("elasticsearch.action"), experimental("RefreshAction")), + equalTo(stringKey("elasticsearch.request"), experimental("RefreshRequest")), + equalTo(stringKey("elasticsearch.request.indices"), experimental(indexName)))); + } + + private static List refreshBroadcastActionAttributes(String indexName) { + List assertions = refreshActionAttributes(indexName); + assertions.addAll( + asList( + equalTo(longKey("elasticsearch.shard.broadcast.failed"), experimental(0)), + equalTo(longKey("elasticsearch.shard.broadcast.successful"), experimental(5)), + equalTo(longKey("elasticsearch.shard.broadcast.total"), experimental(10)))); + return assertions; } @Test @@ -407,8 +445,12 @@ class Elasticsearch53SpringTemplateTest { maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "SearchAction"), - equalTo(stringKey("elasticsearch.action"), "SearchAction"), - equalTo(stringKey("elasticsearch.request"), "SearchRequest"), - equalTo(stringKey("elasticsearch.request.indices"), indexName)))); + equalTo( + stringKey("elasticsearch.action"), experimental("SearchAction")), + equalTo( + stringKey("elasticsearch.request"), experimental("SearchRequest")), + equalTo( + stringKey("elasticsearch.request.indices"), + experimental(indexName))))); } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/ElasticsearchSpringTest.java b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/ElasticsearchSpringTest.java new file mode 100644 index 0000000000..f8ad47f0ef --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/v5_3/springdata/ElasticsearchSpringTest.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.elasticsearch.transport.v5_3.springdata; + +abstract class ElasticsearchSpringTest { + protected static final String EXPERIMENTAL_FLAG = + "otel.instrumentation.elasticsearch.experimental-span-attributes"; + + protected static String experimental(String value) { + if (!Boolean.getBoolean(EXPERIMENTAL_FLAG)) { + return null; + } + return value; + } + + protected static Long experimental(long value) { + if (!Boolean.getBoolean(EXPERIMENTAL_FLAG)) { + return null; + } + return value; + } +} diff --git a/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml new file mode 100644 index 0000000000..7a02d702e3 --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-transport-5.3/metadata.yaml @@ -0,0 +1,8 @@ +description: > + This instrumentation provides client spans 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. + type: boolean + default: false diff --git a/instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/build.gradle.kts index 6fff8fea4a..2dc9e8284a 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-transport-6.0/javaagent/build.gradle.kts @@ -97,16 +97,34 @@ testing { tasks { withType().configureEach { systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) - // TODO run tests both with and without experimental span attributes - jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + systemProperty("collectSpans", true) } - val testStableSemconv by registering(Test::class) { - jvmArgs("-Dotel.semconv-stability.opt-in=database") + val testSuites = testing.suites.withType(JvmTestSuite::class) + + val stableSemconvSuites = testSuites.map { suite -> + register("${suite.name}StableSemconv") { + testClassesDirs = suite.sources.output.classesDirs + classpath = suite.sources.runtimeClasspath + + jvmArgs("-Dotel.semconv-stability.opt-in=database") + systemProperty("metaDataConfig", "otel.semconv-stability.opt-in=database") + } + } + + val experimentalSuites = testSuites.map { suite -> + register("${suite.name}Experimental") { + testClassesDirs = suite.sources.output.classesDirs + classpath = suite.sources.runtimeClasspath + + jvmArgs("-Dotel.instrumentation.elasticsearch.experimental-span-attributes=true") + systemProperty("metaDataConfig", "otel.instrumentation.elasticsearch.experimental-span-attributes=true") + } } check { - dependsOn(testing.suites) - dependsOn(testStableSemconv) + dependsOn(testing.suites, stableSemconvSuites, experimentalSuites) } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml b/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml new file mode 100644 index 0000000000..7a02d702e3 --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-transport-6.0/metadata.yaml @@ -0,0 +1,8 @@ +description: > + This instrumentation provides client spans 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. + type: boolean + default: false diff --git a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchClientTest.java index 8f7e41d4c6..38bcb88a9d 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchClientTest.java @@ -44,6 +44,9 @@ abstract class AbstractElasticsearchClientTest { protected static final AttributeKey ELASTICSEARCH_VERSION = AttributeKey.longKey("elasticsearch.version"); + protected static final String EXPERIMENTAL_FLAG = + "otel.instrumentation.elasticsearch.experimental-span-attributes"; + @RegisterExtension protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); @@ -96,6 +99,20 @@ abstract class AbstractElasticsearchClientTest { return result.get(); } + protected static String experimental(String value) { + if (!Boolean.getBoolean(EXPERIMENTAL_FLAG)) { + return null; + } + return value; + } + + protected static Long experimental(long value) { + if (!Boolean.getBoolean(EXPERIMENTAL_FLAG)) { + return null; + } + return value; + } + static class Result { private final CountDownLatch latch = new CountDownLatch(1); private RESPONSE response; 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 e697c9e5e5..5988fd9fd9 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 @@ -12,6 +12,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equal 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; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Named.named; @@ -23,7 +24,6 @@ import io.opentelemetry.sdk.testing.assertj.AttributeAssertion; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -76,8 +76,8 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "ClusterHealthAction"), - equalTo(ELASTICSEARCH_ACTION, "ClusterHealthAction"), - equalTo(ELASTICSEARCH_REQUEST, "ClusterHealthRequest")), + equalTo(ELASTICSEARCH_ACTION, experimental("ClusterHealthAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("ClusterHealthRequest"))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) @@ -107,14 +107,14 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti List assertions = new ArrayList<>( - Arrays.asList( + asList( equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, "invalid-index"))); + equalTo(ELASTICSEARCH_ACTION, experimental("GetAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("GetRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental("invalid-index")))); if (SemconvStability.emitStableDatabaseSemconv()) { assertions.add(equalTo(ERROR_TYPE, "org.elasticsearch.index.IndexNotFoundException")); @@ -152,6 +152,22 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti .actionGet(TIMEOUT); } + private static List getActionAttributes( + String indexName, String indexType, String id, long version) { + return new ArrayList<>( + asList( + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "GetAction"), + equalTo(ELASTICSEARCH_ACTION, experimental("GetAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("GetRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName)), + equalTo(ELASTICSEARCH_TYPE, experimental(indexType)), + equalTo(ELASTICSEARCH_ID, experimental(id)), + equalTo(ELASTICSEARCH_VERSION, experimental(version)))); + } + @Test void elasticsearchGet() { String indexName = "test-index"; @@ -195,9 +211,9 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "CreateIndexAction"), - equalTo(ELASTICSEARCH_ACTION, "CreateIndexAction"), - equalTo(ELASTICSEARCH_REQUEST, "CreateIndexRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName))), + equalTo(ELASTICSEARCH_ACTION, experimental("CreateIndexAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("CreateIndexRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName)))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -209,8 +225,8 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "ClusterHealthAction"), - equalTo(ELASTICSEARCH_ACTION, "ClusterHealthAction"), - equalTo(ELASTICSEARCH_REQUEST, "ClusterHealthRequest"))), + equalTo(ELASTICSEARCH_ACTION, experimental("ClusterHealthAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("ClusterHealthRequest")))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -218,16 +234,7 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(ELASTICSEARCH_TYPE, indexType), - equalTo(ELASTICSEARCH_ID, id), - equalTo(ELASTICSEARCH_VERSION, -1))), + getActionAttributes(indexName, indexType, id, -1))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -235,19 +242,27 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - addIndexActionAttributes( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "IndexAction"), - equalTo(ELASTICSEARCH_ACTION, "IndexAction"), - equalTo(ELASTICSEARCH_REQUEST, "IndexRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(stringKey("elasticsearch.request.write.type"), indexType), - equalTo(longKey("elasticsearch.response.status"), 201), - equalTo(longKey("elasticsearch.shard.replication.total"), 2), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0)))), + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "IndexAction"), + equalTo(ELASTICSEARCH_ACTION, experimental("IndexAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("IndexRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName)), + equalTo( + stringKey("elasticsearch.request.write.type"), + experimental(indexType)), + equalTo(longKey("elasticsearch.response.status"), experimental(201)), + equalTo( + longKey("elasticsearch.shard.replication.total"), experimental(2)), + equalTo( + longKey("elasticsearch.shard.replication.successful"), + experimental(1)), + equalTo( + longKey("elasticsearch.shard.replication.failed"), experimental(0)), + equalTo( + longKey("elasticsearch.request.write.version"), + hasWriteVersion() ? experimental(-3) : null))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -255,27 +270,10 @@ public abstract class AbstractElasticsearchNodeClientTest extends AbstractElasti .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(ELASTICSEARCH_TYPE, indexType), - equalTo(ELASTICSEARCH_ID, id), - equalTo(ELASTICSEARCH_VERSION, 1)))); + getActionAttributes(indexName, indexType, id, 1)))); } protected boolean hasWriteVersion() { return true; } - - private List addIndexActionAttributes(AttributeAssertion... assertions) { - List result = new ArrayList<>(Arrays.asList(assertions)); - if (hasWriteVersion()) { - result.add(equalTo(longKey("elasticsearch.request.write.version"), -3)); - } - return result; - } } diff --git a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchTransportClientTest.java b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchTransportClientTest.java index a7298b0346..7d9f9c45a4 100644 --- a/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchTransportClientTest.java +++ b/instrumentation/elasticsearch/elasticsearch-transport-common/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/transport/AbstractElasticsearchTransportClientTest.java @@ -18,6 +18,7 @@ import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_PORT; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_TYPE; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Named.named; @@ -29,7 +30,6 @@ import io.opentelemetry.sdk.testing.assertj.AttributeAssertion; import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -91,14 +91,29 @@ public abstract class AbstractElasticsearchTransportClientTest maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "ClusterHealthAction"), - equalTo(ELASTICSEARCH_ACTION, "ClusterHealthAction"), - equalTo(ELASTICSEARCH_REQUEST, "ClusterHealthRequest"))), + equalTo(ELASTICSEARCH_ACTION, experimental("ClusterHealthAction")), + equalTo( + ELASTICSEARCH_REQUEST, experimental("ClusterHealthRequest")))), span -> span.hasName("callback") .hasKind(SpanKind.INTERNAL) .hasParent(trace.getSpan(0)))); } + private List addNetworkTypeAttribute(AttributeAssertion... assertions) { + List result = new ArrayList<>(asList(assertions)); + if (hasNetworkType()) { + result.add( + satisfies( + NETWORK_TYPE, + k -> + k.satisfiesAnyOf( + val -> assertThat(val).isEqualTo("ipv4"), + val -> assertThat(val).isEqualTo("ipv6")))); + } + return result; + } + private Stream errorArguments() { return Stream.of( Arguments.of( @@ -122,14 +137,14 @@ public abstract class AbstractElasticsearchTransportClientTest List assertions = new ArrayList<>( - Arrays.asList( + asList( equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, "invalid-index"))); + equalTo(ELASTICSEARCH_ACTION, experimental("GetAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("GetRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental("invalid-index")))); if (SemconvStability.emitStableDatabaseSemconv()) { assertions.add(equalTo(ERROR_TYPE, "org.elasticsearch.transport.RemoteTransportException")); @@ -216,9 +231,9 @@ public abstract class AbstractElasticsearchTransportClientTest maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "CreateIndexAction"), - equalTo(ELASTICSEARCH_ACTION, "CreateIndexAction"), - equalTo(ELASTICSEARCH_REQUEST, "CreateIndexRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName)))), + equalTo(ELASTICSEARCH_ACTION, experimental("CreateIndexAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("CreateIndexRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName))))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -230,8 +245,8 @@ public abstract class AbstractElasticsearchTransportClientTest maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), getPutMappingActionName()), - equalTo(ELASTICSEARCH_ACTION, getPutMappingActionName()), - equalTo(ELASTICSEARCH_REQUEST, "PutMappingRequest"))), + equalTo(ELASTICSEARCH_ACTION, experimental(getPutMappingActionName())), + equalTo(ELASTICSEARCH_REQUEST, experimental("PutMappingRequest")))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -239,21 +254,33 @@ public abstract class AbstractElasticsearchTransportClientTest .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - addIndexActionAttributes( + addNetworkTypeAttribute( equalTo(NETWORK_PEER_ADDRESS, getAddress()), equalTo(NETWORK_PEER_PORT, getPort()), equalTo( maybeStable(DB_SYSTEM), DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), equalTo(maybeStable(DB_OPERATION), "IndexAction"), - equalTo(ELASTICSEARCH_ACTION, "IndexAction"), - equalTo(ELASTICSEARCH_REQUEST, "IndexRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(stringKey("elasticsearch.request.write.type"), indexType), - equalTo(longKey("elasticsearch.response.status"), 201), - equalTo(longKey("elasticsearch.shard.replication.total"), 2), - equalTo(longKey("elasticsearch.shard.replication.successful"), 1), - equalTo(longKey("elasticsearch.shard.replication.failed"), 0)))), + equalTo(ELASTICSEARCH_ACTION, experimental("IndexAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("IndexRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName)), + equalTo( + stringKey("elasticsearch.request.write.type"), + experimental(indexType)), + equalTo( + longKey("elasticsearch.response.status"), experimental(201)), + equalTo( + longKey("elasticsearch.shard.replication.total"), + experimental(2)), + equalTo( + longKey("elasticsearch.shard.replication.successful"), + experimental(1)), + equalTo( + longKey("elasticsearch.shard.replication.failed"), + experimental(0)), + equalTo( + longKey("elasticsearch.request.write.version"), + hasWriteVersion() ? experimental(-3) : null)))), // moved here by sorting, chronologically happens before PutMappingAction trace -> trace.hasSpansSatisfyingExactly( @@ -262,19 +289,7 @@ public abstract class AbstractElasticsearchTransportClientTest .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - addNetworkTypeAttribute( - equalTo(NETWORK_PEER_ADDRESS, getAddress()), - equalTo(NETWORK_PEER_PORT, getPort()), - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(ELASTICSEARCH_TYPE, indexType), - equalTo(ELASTICSEARCH_ID, id), - equalTo(ELASTICSEARCH_VERSION, -1)))), + getActionAttributes(indexName, indexType, id, -1))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -282,48 +297,32 @@ public abstract class AbstractElasticsearchTransportClientTest .hasKind(SpanKind.CLIENT) .hasNoParent() .hasAttributesSatisfyingExactly( - addNetworkTypeAttribute( - equalTo(NETWORK_PEER_ADDRESS, getAddress()), - equalTo(NETWORK_PEER_PORT, getPort()), - equalTo( - maybeStable(DB_SYSTEM), - DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), - equalTo(maybeStable(DB_OPERATION), "GetAction"), - equalTo(ELASTICSEARCH_ACTION, "GetAction"), - equalTo(ELASTICSEARCH_REQUEST, "GetRequest"), - equalTo(ELASTICSEARCH_REQUEST_INDICES, indexName), - equalTo(ELASTICSEARCH_TYPE, indexType), - equalTo(ELASTICSEARCH_ID, id), - equalTo(ELASTICSEARCH_VERSION, 1))))); + getActionAttributes(indexName, indexType, id, 1)))); } - protected boolean hasNetworkType() { - return false; - } - - private List addNetworkTypeAttribute(AttributeAssertion... assertions) { - List result = new ArrayList<>(Arrays.asList(assertions)); - if (hasNetworkType()) { - result.add( - satisfies( - NETWORK_TYPE, - k -> - k.satisfiesAnyOf( - val -> assertThat(val).isEqualTo("ipv4"), - val -> assertThat(val).isEqualTo("ipv6")))); - } - return result; + private List getActionAttributes( + String indexName, String indexType, String id, long version) { + return new ArrayList<>( + addNetworkTypeAttribute( + equalTo(NETWORK_PEER_ADDRESS, getAddress()), + equalTo(NETWORK_PEER_PORT, getPort()), + equalTo( + maybeStable(DB_SYSTEM), + DbIncubatingAttributes.DbSystemIncubatingValues.ELASTICSEARCH), + equalTo(maybeStable(DB_OPERATION), "GetAction"), + equalTo(ELASTICSEARCH_ACTION, experimental("GetAction")), + equalTo(ELASTICSEARCH_REQUEST, experimental("GetRequest")), + equalTo(ELASTICSEARCH_REQUEST_INDICES, experimental(indexName)), + equalTo(ELASTICSEARCH_TYPE, experimental(indexType)), + equalTo(ELASTICSEARCH_ID, experimental(id)), + equalTo(ELASTICSEARCH_VERSION, experimental(version)))); } protected boolean hasWriteVersion() { return true; } - private List addIndexActionAttributes(AttributeAssertion... assertions) { - List result = new ArrayList<>(addNetworkTypeAttribute(assertions)); - if (hasWriteVersion()) { - result.add(equalTo(longKey("elasticsearch.request.write.version"), -3)); - } - return result; + protected boolean hasNetworkType() { + return false; } }