From e5a5830f04883fccc3143182ded913296870ee2c Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Tue, 26 Aug 2025 15:51:54 -0400 Subject: [PATCH 1/2] Metadata for graphql-java --- docs/instrumentation-list.yaml | 69 +++++++++++++++++++ instrumentation-docs/instrumentations.sh | 3 + .../javaagent/build.gradle.kts | 2 + .../graphql-java-12.0/metadata.yaml | 13 ++++ .../javaagent/build.gradle.kts | 17 ++++- .../graphql-java-20.0/metadata.yaml | 21 ++++++ .../graphql/AbstractGraphqlTest.java | 15 ++-- 7 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 instrumentation/graphql-java/graphql-java-12.0/metadata.yaml create mode 100644 instrumentation/graphql-java/graphql-java-20.0/metadata.yaml diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index 8978ac5e1557..fae731f13678 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -3014,6 +3014,7 @@ libraries: attributes: [] graphql: - name: graphql-java-12.0 + description: This instrumentation enables spans for GraphQL Java operations. source_path: instrumentation/graphql-java/graphql-java-12.0 scope: name: io.opentelemetry.graphql-java-12.0 @@ -3022,7 +3023,30 @@ libraries: - com.graphql-java:graphql-java:[12,20) library: - com.graphql-java:graphql-java:[12.0,19.+) + configurations: + - name: otel.instrumentation.graphql.query-sanitizer.enabled + description: Enables sanitization of sensitive information from queries so they + aren't added as span attributes. + type: boolean + default: true + - name: otel.instrumentation.graphql.add-operation-name-to-span-name.enabled + description: | + Whether GraphQL operation name is added to the span name. WARNING: The GraphQL operation name is provided by the client and can have high cardinality. Use only when the server is not exposed to malicious clients. + type: boolean + default: false + telemetry: + - when: default + spans: + - span_kind: INTERNAL + attributes: + - name: graphql.document + type: STRING + - name: graphql.operation.name + type: STRING + - name: graphql.operation.type + type: STRING - name: graphql-java-20.0 + description: This instrumentation enables spans for GraphQL Java operations. source_path: instrumentation/graphql-java/graphql-java-20.0 minimum_java_version: 11 scope: @@ -3032,6 +3056,51 @@ libraries: - com.graphql-java:graphql-java:[20,) library: - com.graphql-java:graphql-java:20.0 + configurations: + - name: otel.instrumentation.graphql.query-sanitizer.enabled + description: Enables sanitization of sensitive information from queries so they + aren't added as span attributes. + type: boolean + default: true + - name: otel.instrumentation.graphql.add-operation-name-to-span-name.enabled + description: | + Whether GraphQL operation name is added to the span name. WARNING: The GraphQL operation name is provided by the client and can have high cardinality. Use only when the server is not exposed to malicious clients. + type: boolean + default: false + - name: otel.instrumentation.graphql.data-fetcher.enabled + description: Enables span generation for data fetchers. + type: boolean + default: false + - name: otel.instrumentation.graphql.trivial-data-fetcher.enabled + description: Whether to create spans for trivial data fetchers. A trivial data + fetcher is one that simply maps data from an object to a field. + type: boolean + default: false + telemetry: + - when: default + spans: + - span_kind: INTERNAL + attributes: + - name: graphql.document + type: STRING + - name: graphql.operation.name + type: STRING + - name: graphql.operation.type + type: STRING + - when: otel.instrumentation.graphql.data-fetcher.enabled=true + spans: + - span_kind: INTERNAL + attributes: + - name: graphql.document + type: STRING + - name: graphql.field.name + type: STRING + - name: graphql.field.path + type: STRING + - name: graphql.operation.name + type: STRING + - name: graphql.operation.type + type: STRING grizzly: - name: grizzly-2.3 description: This instrumentation enables HTTP SERVER spans and metrics for Grizzly diff --git a/instrumentation-docs/instrumentations.sh b/instrumentation-docs/instrumentations.sh index 34d537a503fd..5c210128c2e5 100755 --- a/instrumentation-docs/instrumentations.sh +++ b/instrumentation-docs/instrumentations.sh @@ -137,6 +137,9 @@ readonly INSTRUMENTATIONS=( "grails-3.0:javaagent:test" "grizzly-2.3:javaagent:test" "gwt-2.0:javaagent:test" + "graphql-java:graphql-java-12.0:javaagent:test" + "graphql-java:graphql-java-20.0:javaagent:test" + "graphql-java:graphql-java-20.0:javaagent:testDataFetcher" ) # Some instrumentation test suites don't run ARM, so we use colima to run them in an x86_64 diff --git a/instrumentation/graphql-java/graphql-java-12.0/javaagent/build.gradle.kts b/instrumentation/graphql-java/graphql-java-12.0/javaagent/build.gradle.kts index 9a24a559281a..d8f20efe533e 100644 --- a/instrumentation/graphql-java/graphql-java-12.0/javaagent/build.gradle.kts +++ b/instrumentation/graphql-java/graphql-java-12.0/javaagent/build.gradle.kts @@ -27,4 +27,6 @@ dependencies { tasks.withType().configureEach { jvmArgs("-Dotel.instrumentation.graphql.add-operation-name-to-span-name.enabled=true") + + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") } diff --git a/instrumentation/graphql-java/graphql-java-12.0/metadata.yaml b/instrumentation/graphql-java/graphql-java-12.0/metadata.yaml new file mode 100644 index 000000000000..7279dc02ed5b --- /dev/null +++ b/instrumentation/graphql-java/graphql-java-12.0/metadata.yaml @@ -0,0 +1,13 @@ +description: This instrumentation enables spans for GraphQL Java operations. +configurations: + - name: otel.instrumentation.graphql.query-sanitizer.enabled + description: Enables sanitization of sensitive information from queries so they aren't added as span attributes. + type: boolean + default: true + - name: otel.instrumentation.graphql.add-operation-name-to-span-name.enabled + description: > + Whether GraphQL operation name is added to the span name. WARNING: The GraphQL operation name is + provided by the client and can have high cardinality. Use only when the server is not exposed to malicious + clients. + type: boolean + default: false diff --git a/instrumentation/graphql-java/graphql-java-20.0/javaagent/build.gradle.kts b/instrumentation/graphql-java/graphql-java-20.0/javaagent/build.gradle.kts index 2d1c55a270f0..12c0823a144a 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/javaagent/build.gradle.kts +++ b/instrumentation/graphql-java/graphql-java-20.0/javaagent/build.gradle.kts @@ -23,9 +23,20 @@ dependencies { testImplementation(project(":instrumentation:graphql-java:graphql-java-common:testing")) } -tasks.withType().configureEach { - jvmArgs("-Dotel.instrumentation.graphql.data-fetcher.enabled=true") - jvmArgs("-Dotel.instrumentation.graphql.add-operation-name-to-span-name.enabled=true") +tasks { + withType().configureEach { + jvmArgs("-Dotel.instrumentation.graphql.add-operation-name-to-span-name.enabled=true") + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + } + + val testDataFetcher by registering(Test::class) { + jvmArgs("-Dotel.instrumentation.graphql.data-fetcher.enabled=true") + systemProperty("metadataConfig", "otel.instrumentation.graphql.data-fetcher.enabled=true") + } + + check { + dependsOn(testDataFetcher) + } } if (findProperty("testLatestDeps") as Boolean) { diff --git a/instrumentation/graphql-java/graphql-java-20.0/metadata.yaml b/instrumentation/graphql-java/graphql-java-20.0/metadata.yaml new file mode 100644 index 000000000000..dc16c2abe4c8 --- /dev/null +++ b/instrumentation/graphql-java/graphql-java-20.0/metadata.yaml @@ -0,0 +1,21 @@ +description: This instrumentation enables spans for GraphQL Java operations. +configurations: + - name: otel.instrumentation.graphql.query-sanitizer.enabled + description: Enables sanitization of sensitive information from queries so they aren't added as span attributes. + type: boolean + default: true + - name: otel.instrumentation.graphql.add-operation-name-to-span-name.enabled + description: > + Whether GraphQL operation name is added to the span name. WARNING: The GraphQL operation name is + provided by the client and can have high cardinality. Use only when the server is not exposed to malicious + clients. + type: boolean + default: false + - name: otel.instrumentation.graphql.data-fetcher.enabled + description: Enables span generation for data fetchers. + type: boolean + default: false + - name: otel.instrumentation.graphql.trivial-data-fetcher.enabled + description: Whether to create spans for trivial data fetchers. A trivial data fetcher is one that simply maps data from an object to a field. + type: boolean + default: false diff --git a/instrumentation/graphql-java/graphql-java-common/testing/src/main/java/io/opentelemetry/instrumentation/graphql/AbstractGraphqlTest.java b/instrumentation/graphql-java/graphql-java-common/testing/src/main/java/io/opentelemetry/instrumentation/graphql/AbstractGraphqlTest.java index 351241a569f9..133610aa75dc 100644 --- a/instrumentation/graphql-java/graphql-java-common/testing/src/main/java/io/opentelemetry/instrumentation/graphql/AbstractGraphqlTest.java +++ b/instrumentation/graphql-java/graphql-java-common/testing/src/main/java/io/opentelemetry/instrumentation/graphql/AbstractGraphqlTest.java @@ -44,6 +44,9 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public abstract class AbstractGraphqlTest { + private static final String DATA_FETCHER_PROPERTY = + "otel.instrumentation.graphql.data-fetcher.enabled"; + private final List> books = new ArrayList<>(); private final List> authors = new ArrayList<>(); @@ -58,6 +61,10 @@ protected boolean hasDataFetcherSpans() { return false; } + private boolean includeDataFetcher() { + return Boolean.getBoolean(DATA_FETCHER_PROPERTY) && hasDataFetcherSpans(); + } + @BeforeAll void setup() throws IOException { addAuthor("author-1", "John"); @@ -162,7 +169,7 @@ void successfulQuery() { normalizedQueryEqualsTo( GraphqlIncubatingAttributes.GRAPHQL_DOCUMENT, "query findBookById { bookById(id: ?) { name } }"))); - if (hasDataFetcherSpans()) { + if (includeDataFetcher()) { assertions.add( span -> span.hasName("bookById") @@ -174,7 +181,7 @@ void successfulQuery() { assertions.add( span -> span.hasName("fetchBookById") - .hasParent(trace.getSpan(hasDataFetcherSpans() ? 1 : 0))); + .hasParent(trace.getSpan(includeDataFetcher() ? 1 : 0))); trace.hasSpansSatisfyingExactly(assertions); }); @@ -207,7 +214,7 @@ void successfulQueryWithoutName() { normalizedQueryEqualsTo( AttributeKey.stringKey("graphql.document"), "{ bookById(id: ?) { name } }"))); - if (hasDataFetcherSpans()) { + if (includeDataFetcher()) { assertions.add( span -> span.hasName("bookById") @@ -219,7 +226,7 @@ void successfulQueryWithoutName() { assertions.add( span -> span.hasName("fetchBookById") - .hasParent(trace.getSpan(hasDataFetcherSpans() ? 1 : 0))); + .hasParent(trace.getSpan(includeDataFetcher() ? 1 : 0))); trace.hasSpansSatisfyingExactly(assertions); }); } From e0c3646021f1a7ab13fcdb91a956ceb9257eabfc Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Tue, 26 Aug 2025 16:44:25 -0400 Subject: [PATCH 2/2] fix library tests --- .../graphql-java/graphql-java-20.0/library/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/instrumentation/graphql-java/graphql-java-20.0/library/build.gradle.kts b/instrumentation/graphql-java/graphql-java-20.0/library/build.gradle.kts index 79f49cf21985..6dd190a344b1 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/library/build.gradle.kts +++ b/instrumentation/graphql-java/graphql-java-20.0/library/build.gradle.kts @@ -14,3 +14,7 @@ if (findProperty("testLatestDeps") as Boolean) { minJavaVersionSupported.set(JavaVersion.VERSION_11) } } + +tasks.withType().configureEach { + jvmArgs("-Dotel.instrumentation.graphql.data-fetcher.enabled=true") +}