diff --git a/instrumentation/graphql-java/README.md b/instrumentation/graphql-java/README.md index 0509214588..65693b8e5e 100644 --- a/instrumentation/graphql-java/README.md +++ b/instrumentation/graphql-java/README.md @@ -1,8 +1,9 @@ # Settings for the GraphQL instrumentation -| System property | Type | Default | Description | -|--------------------------------------------------------|---------|---------|--------------------------------------------------------------------------------------------| -| `otel.instrumentation.graphql.query-sanitizer.enabled` | Boolean | `true` | Whether to remove sensitive information from query source that is added as span attribute. | +| System property | Type | Default | Description | +|------------------------------------------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `otel.instrumentation.graphql.query-sanitizer.enabled` | Boolean | `true` | Whether to remove sensitive information from query source that is added as span attribute. | +| `otel.instrumentation.graphql.add-operation-name-to-span-name.enabled` | Boolean | `false` | Whether GraphQL operation name is added to the span name.

**WARNING**: GraphQL operation name is provided by the client and can have high cardinality. Use only when the server is not exposed to malicious clients. | # Settings for the GraphQL 20 instrumentation 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 4c21d72dea..9a24a55928 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 @@ -24,3 +24,7 @@ dependencies { latestDepTestLibrary("com.graphql-java:graphql-java:19.+") // see graphql-java-20.0 module } + +tasks.withType().configureEach { + jvmArgs("-Dotel.instrumentation.graphql.add-operation-name-to-span-name.enabled=true") +} diff --git a/instrumentation/graphql-java/graphql-java-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v12_0/GraphqlSingletons.java b/instrumentation/graphql-java/graphql-java-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v12_0/GraphqlSingletons.java index 162a54a627..122a3b3882 100644 --- a/instrumentation/graphql-java/graphql-java-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v12_0/GraphqlSingletons.java +++ b/instrumentation/graphql-java/graphql-java-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v12_0/GraphqlSingletons.java @@ -16,10 +16,15 @@ public final class GraphqlSingletons { private static final boolean QUERY_SANITIZATION_ENABLED = AgentInstrumentationConfig.get() .getBoolean("otel.instrumentation.graphql.query-sanitizer.enabled", true); + private static final boolean ADD_OPERATION_NAME_TO_SPAN_NAME = + AgentInstrumentationConfig.get() + .getBoolean( + "otel.instrumentation.graphql.add-operation-name-to-span-name.enabled", false); private static final GraphQLTelemetry TELEMETRY = GraphQLTelemetry.builder(GlobalOpenTelemetry.get()) .setSanitizeQuery(QUERY_SANITIZATION_ENABLED) + .setAddOperationNameToSpanName(ADD_OPERATION_NAME_TO_SPAN_NAME) .build(); private GraphqlSingletons() {} diff --git a/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetry.java b/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetry.java index 4b6ec25adf..6b7cbb926f 100644 --- a/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetry.java +++ b/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetry.java @@ -27,10 +27,11 @@ public final class GraphQLTelemetry { private final OpenTelemetryInstrumentationHelper helper; - GraphQLTelemetry(OpenTelemetry openTelemetry, boolean sanitizeQuery) { + GraphQLTelemetry( + OpenTelemetry openTelemetry, boolean sanitizeQuery, boolean addOperationNameToSpanName) { helper = OpenTelemetryInstrumentationHelper.create( - openTelemetry, INSTRUMENTATION_NAME, sanitizeQuery); + openTelemetry, INSTRUMENTATION_NAME, sanitizeQuery, addOperationNameToSpanName); } /** diff --git a/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetryBuilder.java b/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetryBuilder.java index b6fabdd808..aa2f47dc62 100644 --- a/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetryBuilder.java +++ b/instrumentation/graphql-java/graphql-java-12.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphQLTelemetryBuilder.java @@ -15,6 +15,7 @@ public final class GraphQLTelemetryBuilder { private final OpenTelemetry openTelemetry; private boolean sanitizeQuery = true; + private boolean addOperationNameToSpanName = false; GraphQLTelemetryBuilder(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; @@ -27,11 +28,23 @@ public final class GraphQLTelemetryBuilder { return this; } + /** + * Sets whether GraphQL operation name is added to the span name. Default is {@code false}. + * + *

WARNING: GraphQL operation name is provided by the client and can have high cardinality. Use + * only when the server is not exposed to malicious clients. + */ + @CanIgnoreReturnValue + public GraphQLTelemetryBuilder setAddOperationNameToSpanName(boolean addOperationNameToSpanName) { + this.addOperationNameToSpanName = addOperationNameToSpanName; + return this; + } + /** * Returns a new {@link GraphQLTelemetry} with the settings of this {@link * GraphQLTelemetryBuilder}. */ public GraphQLTelemetry build() { - return new GraphQLTelemetry(openTelemetry, sanitizeQuery); + return new GraphQLTelemetry(openTelemetry, sanitizeQuery, addOperationNameToSpanName); } } diff --git a/instrumentation/graphql-java/graphql-java-12.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphqlTest.java b/instrumentation/graphql-java/graphql-java-12.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphqlTest.java index 9fcff9a7b3..2b1e5ad109 100644 --- a/instrumentation/graphql-java/graphql-java-12.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphqlTest.java +++ b/instrumentation/graphql-java/graphql-java-12.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v12_0/GraphqlTest.java @@ -23,7 +23,10 @@ class GraphqlTest extends AbstractGraphqlTest { @Override protected void configure(GraphQL.Builder builder) { - GraphQLTelemetry telemetry = GraphQLTelemetry.builder(testing.getOpenTelemetry()).build(); + GraphQLTelemetry telemetry = + GraphQLTelemetry.builder(testing.getOpenTelemetry()) + .setAddOperationNameToSpanName(true) + .build(); builder.instrumentation(telemetry.newInstrumentation()); } } 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 6f6df45ef9..2d1c55a270 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 @@ -25,6 +25,7 @@ dependencies { tasks.withType().configureEach { jvmArgs("-Dotel.instrumentation.graphql.data-fetcher.enabled=true") + jvmArgs("-Dotel.instrumentation.graphql.add-operation-name-to-span-name.enabled=true") } if (findProperty("testLatestDeps") as Boolean) { diff --git a/instrumentation/graphql-java/graphql-java-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v20_0/GraphqlSingletons.java b/instrumentation/graphql-java/graphql-java-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v20_0/GraphqlSingletons.java index 11f08b6c84..ba489efeea 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v20_0/GraphqlSingletons.java +++ b/instrumentation/graphql-java/graphql-java-20.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/graphql/v20_0/GraphqlSingletons.java @@ -22,12 +22,17 @@ public final class GraphqlSingletons { private static final boolean TRIVIAL_DATA_FETCHER_ENABLED = AgentInstrumentationConfig.get() .getBoolean("otel.instrumentation.graphql.trivial-data-fetcher.enabled", false); + private static final boolean ADD_OPERATION_NAME_TO_SPAN_NAME = + AgentInstrumentationConfig.get() + .getBoolean( + "otel.instrumentation.graphql.add-operation-name-to-span-name.enabled", false); private static final GraphQLTelemetry TELEMETRY = GraphQLTelemetry.builder(GlobalOpenTelemetry.get()) .setSanitizeQuery(QUERY_SANITIZATION_ENABLED) .setDataFetcherInstrumentationEnabled(DATA_FETCHER_ENABLED) .setTrivialDataFetcherInstrumentationEnabled(TRIVIAL_DATA_FETCHER_ENABLED) + .setAddOperationNameToSpanName(ADD_OPERATION_NAME_TO_SPAN_NAME) .build(); private GraphqlSingletons() {} diff --git a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetry.java b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetry.java index 75a4aefc86..bc2b1ceed1 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetry.java +++ b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetry.java @@ -34,8 +34,11 @@ public final class GraphQLTelemetry { OpenTelemetry openTelemetry, boolean sanitizeQuery, Instrumenter dataFetcherInstrumenter, - boolean createSpansForTrivialDataFetcher) { - helper = GraphqlInstrumenterFactory.createInstrumentationHelper(openTelemetry, sanitizeQuery); + boolean createSpansForTrivialDataFetcher, + boolean addOperationNameToSpanName) { + helper = + GraphqlInstrumenterFactory.createInstrumentationHelper( + openTelemetry, sanitizeQuery, addOperationNameToSpanName); this.dataFetcherInstrumenter = dataFetcherInstrumenter; this.createSpansForTrivialDataFetcher = createSpansForTrivialDataFetcher; } diff --git a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetryBuilder.java b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetryBuilder.java index 7e23e5f71f..f12d61dfac 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetryBuilder.java +++ b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphQLTelemetryBuilder.java @@ -15,10 +15,9 @@ public final class GraphQLTelemetryBuilder { private final OpenTelemetry openTelemetry; private boolean sanitizeQuery = true; - private boolean dataFetcherInstrumentationEnabled = false; - private boolean trivialDataFetcherInstrumentationEnabled = false; + private boolean addOperationNameToSpanName = false; GraphQLTelemetryBuilder(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; @@ -50,6 +49,18 @@ public final class GraphQLTelemetryBuilder { return this; } + /** + * Sets whether GraphQL operation name is added to the span name. Default is {@code false}. + * + *

WARNING: GraphQL operation name is provided by the client and can have high cardinality. Use + * only when the server is not exposed to malicious clients. + */ + @CanIgnoreReturnValue + public GraphQLTelemetryBuilder setAddOperationNameToSpanName(boolean addOperationNameToSpanName) { + this.addOperationNameToSpanName = addOperationNameToSpanName; + return this; + } + /** * Returns a new {@link GraphQLTelemetry} with the settings of this {@link * GraphQLTelemetryBuilder}. @@ -60,6 +71,7 @@ public final class GraphQLTelemetryBuilder { sanitizeQuery, GraphqlInstrumenterFactory.createDataFetcherInstrumenter( openTelemetry, dataFetcherInstrumentationEnabled), - trivialDataFetcherInstrumentationEnabled); + trivialDataFetcherInstrumentationEnabled, + addOperationNameToSpanName); } } diff --git a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlInstrumenterFactory.java b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlInstrumenterFactory.java index d1391ecde0..1c2cc153da 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlInstrumenterFactory.java +++ b/instrumentation/graphql-java/graphql-java-20.0/library/src/main/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlInstrumenterFactory.java @@ -15,9 +15,9 @@ final class GraphqlInstrumenterFactory { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.graphql-java-20.0"; static OpenTelemetryInstrumentationHelper createInstrumentationHelper( - OpenTelemetry openTelemetry, boolean sanitizeQuery) { + OpenTelemetry openTelemetry, boolean sanitizeQuery, boolean addOperationNameToSpanName) { return OpenTelemetryInstrumentationHelper.create( - openTelemetry, INSTRUMENTATION_NAME, sanitizeQuery); + openTelemetry, INSTRUMENTATION_NAME, sanitizeQuery, addOperationNameToSpanName); } static Instrumenter createDataFetcherInstrumenter( diff --git a/instrumentation/graphql-java/graphql-java-20.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlTest.java b/instrumentation/graphql-java/graphql-java-20.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlTest.java index c77b596973..792235f51e 100644 --- a/instrumentation/graphql-java/graphql-java-20.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlTest.java +++ b/instrumentation/graphql-java/graphql-java-20.0/library/src/test/java/io/opentelemetry/instrumentation/graphql/v20_0/GraphqlTest.java @@ -41,6 +41,7 @@ class GraphqlTest extends AbstractGraphqlTest { GraphQLTelemetry telemetry = GraphQLTelemetry.builder(testing.getOpenTelemetry()) .setDataFetcherInstrumentationEnabled(true) + .setAddOperationNameToSpanName(true) .build(); builder.instrumentation(telemetry.newInstrumentation()); } @@ -56,6 +57,7 @@ class GraphqlTest extends AbstractGraphqlTest { GraphQLTelemetry telemetry = GraphQLTelemetry.builder(testing.getOpenTelemetry()) .setDataFetcherInstrumentationEnabled(true) + .setAddOperationNameToSpanName(true) .build(); GraphQL graphql = @@ -118,6 +120,7 @@ class GraphqlTest extends AbstractGraphqlTest { GraphQLTelemetry.builder(testing.getOpenTelemetry()) .setDataFetcherInstrumentationEnabled(true) .setTrivialDataFetcherInstrumentationEnabled(true) + .setAddOperationNameToSpanName(true) .build(); GraphQL graphql = @@ -194,6 +197,7 @@ class GraphqlTest extends AbstractGraphqlTest { GraphQLTelemetry.builder(testing.getOpenTelemetry()) .setDataFetcherInstrumentationEnabled(false) .setTrivialDataFetcherInstrumentationEnabled(true) + .setAddOperationNameToSpanName(true) .build(); GraphQL graphql = diff --git a/instrumentation/graphql-java/graphql-java-common/library/src/main/java/io/opentelemetry/instrumentation/graphql/internal/OpenTelemetryInstrumentationHelper.java b/instrumentation/graphql-java/graphql-java-common/library/src/main/java/io/opentelemetry/instrumentation/graphql/internal/OpenTelemetryInstrumentationHelper.java index ab8538450c..d0ef609747 100644 --- a/instrumentation/graphql-java/graphql-java-common/library/src/main/java/io/opentelemetry/instrumentation/graphql/internal/OpenTelemetryInstrumentationHelper.java +++ b/instrumentation/graphql-java/graphql-java-common/library/src/main/java/io/opentelemetry/instrumentation/graphql/internal/OpenTelemetryInstrumentationHelper.java @@ -48,16 +48,22 @@ public final class OpenTelemetryInstrumentationHelper { private final Instrumenter instrumenter; private final boolean sanitizeQuery; + private final boolean addOperationNameToSpanName; private OpenTelemetryInstrumentationHelper( Instrumenter instrumenter, - boolean sanitizeQuery) { + boolean sanitizeQuery, + boolean addOperationNameToSpanName) { this.instrumenter = instrumenter; this.sanitizeQuery = sanitizeQuery; + this.addOperationNameToSpanName = addOperationNameToSpanName; } public static OpenTelemetryInstrumentationHelper create( - OpenTelemetry openTelemetry, String instrumentationName, boolean sanitizeQuery) { + OpenTelemetry openTelemetry, + String instrumentationName, + boolean sanitizeQuery, + boolean addOperationNameToSpanName) { InstrumenterBuilder builder = Instrumenter.builder( openTelemetry, instrumentationName, ignored -> "GraphQL Operation") @@ -76,7 +82,8 @@ public final class OpenTelemetryInstrumentationHelper { }); builder.addAttributesExtractor(new GraphqlAttributesExtractor()); - return new OpenTelemetryInstrumentationHelper(builder.buildInstrumenter(), sanitizeQuery); + return new OpenTelemetryInstrumentationHelper( + builder.buildInstrumenter(), sanitizeQuery, addOperationNameToSpanName); } public InstrumentationContext beginExecution( @@ -118,7 +125,7 @@ public final class OpenTelemetryInstrumentationHelper { String operationName = operationDefinition.getName(); String spanName = operationType; - if (operationName != null && !operationName.isEmpty()) { + if (addOperationNameToSpanName && operationName != null && !operationName.isEmpty()) { spanName += " " + operationName; } span.updateName(spanName);