From 91368ad6444de5a08c41f4fe2d062f5d8ec33856 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 13 Jun 2026 18:56:25 -0700 Subject: [PATCH] Add DB client collection semconv API --- .../db/DbClientAttributesExtractor.java | 4 +- .../semconv/db/DbClientAttributesGetter.java | 17 ++++++ .../semconv/db/DbClientSpanNameExtractor.java | 29 +++++----- .../db/SqlClientAttributesExtractor.java | 34 +++++++++-- .../SqlClientAttributesExtractorBuilder.java | 8 ++- .../semconv/db/SqlClientAttributesGetter.java | 57 ++++++++++++++----- .../db/DbClientAttributesExtractorTest.java | 20 ++++++- .../db/DbClientSpanNameExtractorTest.java | 47 ++++++++++++--- .../v2_4/InfluxDbAttributesGetter.java | 47 +++++++-------- .../v2_4/InfluxDbImplInstrumentation.java | 36 +++++++----- ...xDbRequest.java => InfluxDbOperation.java} | 20 +++---- .../influxdb/v2_4/InfluxDbQuery.java | 28 +++++++++ .../v2_4/InfluxDbQueryAttributesGetter.java | 56 ++++++++++++++++++ .../influxdb/v2_4/InfluxDbScope.java | 23 ++++---- .../influxdb/v2_4/InfluxDbSingletons.java | 43 ++++++++++---- .../influxdb/v2_4/InfluxDbClientTest.java | 31 +++++++--- .../influxdb/v2_4/InfluxDbClient24Test.java | 7 ++- 17 files changed, 373 insertions(+), 134 deletions(-) rename instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/{InfluxDbRequest.java => InfluxDbOperation.java} (50%) create mode 100644 instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQuery.java create mode 100644 instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQueryAttributesGetter.java diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractor.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractor.java index a52425662a3a..e2c5913b00c9 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractor.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractor.java @@ -7,6 +7,7 @@ import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldDatabaseSemconv; import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; +import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_BATCH_SIZE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; @@ -99,6 +100,7 @@ static void onStartCommon( attributes.put( DB_SYSTEM_NAME, SemconvStability.stableDbSystemName(getter.getDbSystemName(request))); attributes.put(DB_NAMESPACE, getter.getDbNamespace(request)); + attributes.put(DB_COLLECTION_NAME, getter.getDbCollectionName(request)); attributes.put(DB_QUERY_TEXT, getter.getDbQueryText(request)); attributes.put(DB_OPERATION_NAME, getter.getDbOperationName(request)); attributes.put(DB_QUERY_SUMMARY, getter.getDbQuerySummary(request)); @@ -112,7 +114,7 @@ static void onStartCommon( attributes.put(DB_NAME, getter.getDbName(request)); attributes.put(DB_CONNECTION_STRING, getter.getConnectionString(request)); attributes.put(DB_STATEMENT, getter.getDbQueryText(request)); - attributes.put(DB_OPERATION, getter.getDbOperationName(request)); + attributes.put(DB_OPERATION, getter.getDbOperation(request)); } // Query parameters are an incubating feature and work with both old and new semconv diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesGetter.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesGetter.java index 3a9aa460c635..400b32669939 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesGetter.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesGetter.java @@ -38,6 +38,17 @@ default String getDbQuerySummary(REQUEST request) { @Nullable String getDbOperationName(REQUEST request); + /** + * Returns the old db.operation value. This is only used for old semantic conventions. + * + * @deprecated Use {@link #getDbOperationName(Object)} instead. + */ + @Deprecated // to be removed in 3.0 + @Nullable + default String getDbOperation(REQUEST request) { + return getDbOperationName(request); + } + // TODO: make this required to implement String getDbSystemName(REQUEST request); @@ -59,6 +70,12 @@ default String getDbSystem(REQUEST request) { @Nullable String getDbNamespace(REQUEST request); + // TODO: make this required to implement? + @Nullable + default String getDbCollectionName(REQUEST request) { + return null; + } + /** * Returns the old db.name value. This is only used for old semantic conventions. * diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractor.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractor.java index 28172e8cb82e..02bfdfc3720a 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractor.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractor.java @@ -163,11 +163,15 @@ public String extract(REQUEST request) { if (querySummary != null) { return querySummary; } - String operationName = getter.getDbOperationName(request); - return computeSpanNameStable(getter, request, operationName, null, null); + return computeSpanNameStable( + getter, + request, + getter.getDbOperationName(request), + getter.getDbCollectionName(request), + null); } String dbName = getter.getDbName(request); - String operationName = getter.getDbOperationName(request); + String operationName = getter.getDbOperation(request); return computeSpanName(dbName, operationName, null, null); } } @@ -189,16 +193,10 @@ public String extract(REQUEST request) { if (rawQueryTexts.isEmpty()) { if (emitStableDatabaseSemconv()) { - String querySummary = getter.getDbQuerySummary(request); - if (querySummary != null) { - return querySummary; - } - String operationName = getter.getDbOperationName(request); - return computeSpanNameStable(getter, request, operationName, null, null); + return computeSpanNameStable(getter, request, null, null, null); } String dbName = getter.getDbName(request); - String operationName = getter.getDbOperationName(request); - return computeSpanName(dbName, operationName, null, null); + return computeSpanName(dbName, null, null, null); } if (!emitStableDatabaseSemconv()) { @@ -224,7 +222,11 @@ public String extract(REQUEST request) { return batch ? "BATCH " + querySummary : querySummary; } return computeSpanNameStable( - getter, request, batch ? "BATCH" : null, null, analyzedQuery.getStoredProcedureName()); + getter, + request, + batch ? "BATCH" : null, + analyzedQuery.getCollectionName(), + analyzedQuery.getStoredProcedureName()); } MultiQuery multiQuery = MultiQuery.analyzeWithSummary(rawQueryTexts, dialect); @@ -276,9 +278,6 @@ public String extract(REQUEST request) { SqlQuery analyzedQuery = SqlQueryAnalyzerUtil.analyze(rawQuery, dialect); operationName = analyzedQuery.getOperationName(); } - if (operationName == null) { - operationName = getter.getDbOperationName(request); - } return computeSpanName(dbName, operationName, null, null); } } diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractor.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractor.java index 874de62b85f5..a995ee2e242b 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractor.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractor.java @@ -7,12 +7,15 @@ import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldDatabaseSemconv; import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; +import static io.opentelemetry.instrumentation.api.internal.SemconvStability.stableDbSystemName; import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; +import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_BATCH_SIZE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_SUMMARY; import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_TEXT; import static io.opentelemetry.semconv.DbAttributes.DB_STORED_PROCEDURE_NAME; +import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.AttributesBuilder; @@ -22,7 +25,9 @@ import io.opentelemetry.instrumentation.api.internal.SpanKeyProvider; import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesExtractor; import io.opentelemetry.instrumentation.api.semconv.network.internal.InternalNetworkAttributesExtractor; +import io.opentelemetry.semconv.AttributeKeyTemplate; import java.util.Collection; +import java.util.Map; import javax.annotation.Nullable; /** @@ -39,8 +44,15 @@ public final class SqlClientAttributesExtractor implements AttributesExtractor, SpanKeyProvider { // copied from DbIncubatingAttributes + private static final AttributeKey DB_NAME = AttributeKey.stringKey("db.name"); + private static final AttributeKey DB_SYSTEM = AttributeKey.stringKey("db.system"); + private static final AttributeKey DB_USER = AttributeKey.stringKey("db.user"); + private static final AttributeKey DB_CONNECTION_STRING = + AttributeKey.stringKey("db.connection_string"); private static final AttributeKey DB_OPERATION = AttributeKey.stringKey("db.operation"); private static final AttributeKey DB_STATEMENT = AttributeKey.stringKey("db.statement"); + private static final AttributeKeyTemplate DB_QUERY_PARAMETER = + AttributeKeyTemplate.stringKeyTemplate("db.query.parameter"); /** Creates the SQL client attributes extractor with default configuration. */ public static AttributesExtractor create( @@ -141,10 +153,24 @@ public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST } } - // calling this last so explicit getDbOperationName(), getDbCollectionName(), - // getDbQueryText(), and getDbQuerySummary() implementations can override - // the parsed values from above - DbClientAttributesExtractor.onStartCommon(attributes, getter, request, captureQueryParameters); + if (emitStableDatabaseSemconv()) { + attributes.put(DB_SYSTEM_NAME, stableDbSystemName(getter.getDbSystemName(request))); + attributes.put(DB_NAMESPACE, getter.getDbNamespace(request)); + } + if (emitOldDatabaseSemconv()) { + attributes.put(DB_SYSTEM, getter.getDbSystem(request)); + attributes.put(DB_USER, getter.getUser(request)); + attributes.put(DB_NAME, getter.getDbName(request)); + attributes.put(DB_CONNECTION_STRING, getter.getConnectionString(request)); + } + if (captureQueryParameters && !isBatch) { + Map queryParameters = getter.getDbQueryParameters(request); + if (queryParameters != null && !queryParameters.isEmpty()) { + for (Map.Entry entry : queryParameters.entrySet()) { + attributes.put(DB_QUERY_PARAMETER.getAttributeKey(entry.getKey()), entry.getValue()); + } + } + } serverAttributesExtractor.onStart(attributes, parentContext, request); } diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractorBuilder.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractorBuilder.java index db1525cd7f04..e247d6c087cb 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractorBuilder.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesExtractorBuilder.java @@ -68,10 +68,12 @@ public SqlClientAttributesExtractorBuilder setCaptureQueryPar } /** - * Sets whether the instrumentation knows that its SQL-like language or request shape is limited - * to a single operation and collection. + * Sets whether {@code db.operation.name} and {@code db.collection.name} can be derived from + * {@code db.query.text}. * - *

For most instrumentations, enabling this will produce invalid semantic conventions. + *

Enable this only when the database system does not support query text with multiple + * operations or multiple collections in non-batch operations. For most instrumentations, enabling + * this will produce invalid semantic conventions. */ @CanIgnoreReturnValue public SqlClientAttributesExtractorBuilder setSingleOperationAndCollection( diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesGetter.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesGetter.java index c3b2ac869b47..eb7d63dc2549 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesGetter.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlClientAttributesGetter.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.api.incubator.semconv.db; import java.util.Collection; -import javax.annotation.Nullable; /** * An interface for getting SQL database client attributes. @@ -23,33 +22,65 @@ public interface SqlClientAttributesGetter extends DbClientAttributesGetter { /** - * SqlClientAttributesExtractor will try to populate db.operation.name based on {@link - * #getRawQueryTexts(REQUEST)}, but this can be used to explicitly provide the operation name. + * SQL instrumentations must not override or call this method. + * + *

Provide raw query text through {@link #getRawQueryTexts(REQUEST)} instead. When the database + * system does not support query text with multiple operations in non-batch operations, enable + * {@link SqlClientAttributesExtractorBuilder#setSingleOperationAndCollection(boolean)} and {@link + * SqlClientAttributesExtractor} will derive {@code db.operation.name} from {@code db.query.text}. + * + * @throws UnsupportedOperationException always */ @Override - @Nullable default String getDbOperationName(REQUEST request) { - return null; + throw new UnsupportedOperationException( + "SQL instrumentations derive db.operation.name from the raw query text"); } /** - * SqlClientAttributesExtractor will try to populate db.query.text based on {@link - * #getRawQueryTexts(REQUEST)}, but this can be used to explicitly provide the query text. + * SQL instrumentations must not override or call this method. + * + *

Provide raw query text through {@link #getRawQueryTexts(REQUEST)} instead. {@link + * SqlClientAttributesExtractor} will derive {@code db.query.text} from the raw query text. + * + * @throws UnsupportedOperationException always */ @Override - @Nullable default String getDbQueryText(REQUEST request) { - return null; + throw new UnsupportedOperationException( + "SQL instrumentations derive db.query.text from the raw query text"); } /** - * SqlClientAttributesExtractor will try to populate db.query.summary based on {@link - * #getRawQueryTexts(REQUEST)}, but this can be used to explicitly provide the query summary. + * SQL instrumentations must not override or call this method. + * + *

Provide raw query text through {@link #getRawQueryTexts(REQUEST)} instead. {@link + * SqlClientAttributesExtractor} will derive {@code db.query.summary} from the raw query text. + * + * @throws UnsupportedOperationException always */ @Override - @Nullable default String getDbQuerySummary(REQUEST request) { - return null; + throw new UnsupportedOperationException( + "SQL instrumentations derive db.query.summary from the raw query text"); + } + + /** + * SQL instrumentations must not override or call this method. + * + *

Provide raw query text through {@link #getRawQueryTexts(REQUEST)} instead. When the database + * system does not support query text with multiple collections in non-batch operations, enable + * {@link SqlClientAttributesExtractorBuilder#setSingleOperationAndCollection(boolean)} and {@link + * SqlClientAttributesExtractor} will derive {@code db.collection.name} from {@code + * db.query.text}. Do not enable that option when the database system supports query text with + * multiple collections in non-batch operations. + * + * @throws UnsupportedOperationException always + */ + @Override + default String getDbCollectionName(REQUEST request) { + throw new UnsupportedOperationException( + "SQL instrumentations derive db.collection.name from the raw query text"); } /** Returns the SQL dialect used by the database. */ diff --git a/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractorTest.java b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractorTest.java index 81ec9bd856e1..7336b737b848 100644 --- a/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractorTest.java +++ b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientAttributesExtractorTest.java @@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitOldDatabaseSemconv; import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableDatabaseSemconv; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.semconv.DbAttributes.DB_COLLECTION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE; import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_SUMMARY; @@ -50,6 +51,11 @@ public String getDbNamespace(Map map) { return map.get("db.namespace"); } + @Override + public String getDbCollectionName(Map map) { + return map.get("db.collection.name"); + } + @Deprecated @Override public String getConnectionString(Map map) { @@ -71,6 +77,12 @@ public String getDbQuerySummary(Map map) { public String getDbOperationName(Map map) { return map.get("db.operation.name"); } + + @Deprecated + @Override + public String getDbOperation(Map map) { + return map.get("db.operation"); + } } @SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation @@ -81,9 +93,11 @@ void shouldExtractAllAvailableAttributes() { request.put("db.system", "myDb"); request.put("db.user", "username"); request.put("db.namespace", "potatoes"); + request.put("db.collection.name", "potato"); request.put("db.connection_string", "mydb:///potatoes"); request.put("db.query.text", "SELECT * FROM potato"); request.put("db.query_summary", "SELECT potato"); + request.put("db.operation", "old SELECT"); request.put("db.operation.name", "SELECT"); Context context = Context.root(); @@ -108,7 +122,8 @@ void shouldExtractAllAvailableAttributes() { entry(DB_NAME, "potatoes"), entry(DB_CONNECTION_STRING, "mydb:///potatoes"), entry(DB_STATEMENT, "SELECT * FROM potato"), - entry(DB_OPERATION, "SELECT"), + entry(DB_OPERATION, "old SELECT"), + entry(DB_COLLECTION_NAME, "potato"), entry(DB_NAMESPACE, "potatoes"), entry(DB_QUERY_TEXT, "SELECT * FROM potato"), entry(DB_QUERY_SUMMARY, "SELECT potato"), @@ -121,11 +136,12 @@ void shouldExtractAllAvailableAttributes() { entry(DB_NAME, "potatoes"), entry(DB_CONNECTION_STRING, "mydb:///potatoes"), entry(DB_STATEMENT, "SELECT * FROM potato"), - entry(DB_OPERATION, "SELECT")); + entry(DB_OPERATION, "old SELECT")); } else if (emitStableDatabaseSemconv()) { assertThat(startAttributes.build()) .containsOnly( entry(DB_SYSTEM_NAME, "myDb"), + entry(DB_COLLECTION_NAME, "potato"), entry(DB_NAMESPACE, "potatoes"), entry(DB_QUERY_TEXT, "SELECT * FROM potato"), entry(DB_QUERY_SUMMARY, "SELECT potato"), diff --git a/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractorTest.java b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractorTest.java index f90a5f60ea49..99dd151dbea8 100644 --- a/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractorTest.java +++ b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/DbClientSpanNameExtractorTest.java @@ -100,11 +100,12 @@ void shouldExtractOperationAndName() { // given DbRequest dbRequest = new DbRequest(); - when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); if (emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); when(dbAttributesGetter.getDbNamespace(dbRequest)).thenReturn("database"); } if (emitOldDatabaseSemconv() && !emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperation(dbRequest)).thenReturn("SELECT"); when(dbAttributesGetter.getDbName(dbRequest)).thenReturn("database"); } @@ -117,12 +118,42 @@ void shouldExtractOperationAndName() { assertThat(spanName).isEqualTo("SELECT database"); } + @Test + void shouldPreferCollectionNameOverNamespace() { + // given + DbRequest dbRequest = new DbRequest(); + + if (emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); + lenient().when(dbAttributesGetter.getDbNamespace(dbRequest)).thenReturn("database"); + when(dbAttributesGetter.getDbCollectionName(dbRequest)).thenReturn("users"); + } + if (emitOldDatabaseSemconv() && !emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperation(dbRequest)).thenReturn("SELECT"); + when(dbAttributesGetter.getDbName(dbRequest)).thenReturn("database"); + } + + SpanNameExtractor underTest = DbClientSpanNameExtractor.create(dbAttributesGetter); + + // when + String spanName = underTest.extract(dbRequest); + + // then + assertThat(spanName) + .isEqualTo(emitStableDatabaseSemconv() ? "SELECT users" : "SELECT database"); + } + @Test void shouldExtractOperation() { // given DbRequest dbRequest = new DbRequest(); - when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); + if (emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); + } + if (emitOldDatabaseSemconv() && !emitStableDatabaseSemconv()) { + when(dbAttributesGetter.getDbOperation(dbRequest)).thenReturn("SELECT"); + } SpanNameExtractor underTest = DbClientSpanNameExtractor.create(dbAttributesGetter); @@ -177,7 +208,7 @@ void shouldUseQuerySummaryWhenAvailable() { when(dbAttributesGetter.getDbQuerySummary(dbRequest)).thenReturn("SELECT users"); } if (emitOldDatabaseSemconv() && !emitStableDatabaseSemconv()) { - when(dbAttributesGetter.getDbOperationName(dbRequest)).thenReturn("SELECT"); + when(dbAttributesGetter.getDbOperation(dbRequest)).thenReturn("SELECT"); when(dbAttributesGetter.getDbName(dbRequest)).thenReturn("database"); } @@ -236,12 +267,11 @@ void shouldExtractFullSpanNameForSingleQueryBatch() { } @Test - void shouldFallBackToExplicitOperationNameForEmptySqlQuery() { + void shouldFallBackToNamespaceForEmptySqlQuery() { // given DbRequest dbRequest = new DbRequest(); when(sqlAttributesGetter.getRawQueryTexts(dbRequest)).thenReturn(emptyList()); - when(sqlAttributesGetter.getDbOperationName(dbRequest)).thenReturn("WRITE"); if (emitStableDatabaseSemconv()) { when(sqlAttributesGetter.getDbNamespace(dbRequest)).thenReturn("mydb"); } @@ -255,7 +285,7 @@ void shouldFallBackToExplicitOperationNameForEmptySqlQuery() { String spanName = underTest.extract(dbRequest); // then - assertThat(spanName).isEqualTo("WRITE mydb"); + assertThat(spanName).isEqualTo("mydb"); } @Test @@ -283,12 +313,11 @@ void shouldPreserveOldSemconvSpanNameForMigration() { @Test @SuppressWarnings("deprecation") // testing deprecated method - void shouldFallBackToExplicitOperationForEmptySqlQueryInMigration() { + void shouldFallBackToNamespaceForEmptySqlQueryInMigration() { // given DbRequest dbRequest = new DbRequest(); when(sqlAttributesGetter.getRawQueryTexts(dbRequest)).thenReturn(emptyList()); - when(sqlAttributesGetter.getDbOperationName(dbRequest)).thenReturn("WRITE"); if (emitStableDatabaseSemconv()) { when(sqlAttributesGetter.getDbNamespace(dbRequest)).thenReturn("mydb"); } @@ -303,7 +332,7 @@ void shouldFallBackToExplicitOperationForEmptySqlQueryInMigration() { String spanName = underTest.extract(dbRequest); // then - assertThat(spanName).isEqualTo("WRITE mydb"); + assertThat(spanName).isEqualTo("mydb"); } static class DbRequest {} diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbAttributesGetter.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbAttributesGetter.java index 07f6606ffe6f..4236ffe08adc 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbAttributesGetter.java +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbAttributesGetter.java @@ -5,58 +5,49 @@ package io.opentelemetry.javaagent.instrumentation.influxdb.v2_4; -import static io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlDialect.DOUBLE_QUOTES_ARE_IDENTIFIERS; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlClientAttributesGetter; -import io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlDialect; -import java.util.Collection; +import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientAttributesGetter; import javax.annotation.Nullable; -final class InfluxDbAttributesGetter implements SqlClientAttributesGetter { +final class InfluxDbAttributesGetter implements DbClientAttributesGetter { + @Nullable @Override - public Collection getRawQueryTexts(InfluxDbRequest request) { - String sql = request.getSql(); - if (sql == null) { - return emptyList(); - } - return singletonList(sql); + public String getDbOperationName(InfluxDbOperation request) { + return request.getOperation(); } + @Nullable @Override - public SqlDialect getSqlDialect(InfluxDbRequest request) { - // "String literals must be surrounded by single quotes." - // https://docs.influxdata.com/influxdb/v2/reference/syntax/influxql/spec/#strings - return DOUBLE_QUOTES_ARE_IDENTIFIERS; + @SuppressWarnings("deprecation") // old database semconv still use db.operation + public String getDbOperation(InfluxDbOperation request) { + String operation = request.getOperation(); + return "write".equals(operation) ? "WRITE" : operation; } - @Nullable @Override - public String getDbOperationName(InfluxDbRequest request) { - return request.getOperationName(); + public String getDbSystemName(InfluxDbOperation request) { + return "influxdb"; } + @Nullable @Override - public String getDbSystemName(InfluxDbRequest request) { - return "influxdb"; + public String getDbNamespace(InfluxDbOperation request) { + return request.getNamespace(); } @Nullable @Override - public String getDbNamespace(InfluxDbRequest request) { - String namespace = request.getNamespace(); - return "".equals(namespace) ? null : namespace; + public String getDbQueryText(InfluxDbOperation request) { + return null; } @Override - public String getServerAddress(InfluxDbRequest request) { + public String getServerAddress(InfluxDbOperation request) { return request.getHost(); } @Override - public Integer getServerPort(InfluxDbRequest request) { + public Integer getServerPort(InfluxDbOperation request) { return request.getPort(); } } diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbImplInstrumentation.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbImplInstrumentation.java index c2283901a673..f9f83c54fa9e 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbImplInstrumentation.java +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbImplInstrumentation.java @@ -6,7 +6,8 @@ package io.opentelemetry.javaagent.instrumentation.influxdb.v2_4; import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; -import static io.opentelemetry.javaagent.instrumentation.influxdb.v2_4.InfluxDbSingletons.instrumenter; +import static io.opentelemetry.javaagent.instrumentation.influxdb.v2_4.InfluxDbSingletons.queryInstrumenter; +import static io.opentelemetry.javaagent.instrumentation.influxdb.v2_4.InfluxDbSingletons.requestInstrumenter; import static net.bytebuddy.matcher.ElementMatchers.isEnum; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; @@ -84,11 +85,11 @@ public static Object[] onEnter( Context parentContext = currentContext(); HttpUrl httpUrl = retrofit.baseUrl(); - InfluxDbRequest influxDbRequest = - InfluxDbRequest.create( - httpUrl.host(), httpUrl.port(), query.getDatabase(), null, query.getCommand()); + InfluxDbQuery influxDbQuery = + InfluxDbQuery.create( + httpUrl.host(), httpUrl.port(), query.getDatabase(), query.getCommand()); - if (!instrumenter().shouldStart(parentContext, influxDbRequest)) { + if (!queryInstrumenter().shouldStart(parentContext, influxDbQuery)) { return null; } @@ -98,7 +99,9 @@ public static Object[] onEnter( newArguments[i] = InfluxDbObjectWrapper.wrap(arguments[i], parentContext); } - return new Object[] {newArguments, InfluxDbScope.start(parentContext, influxDbRequest)}; + return new Object[] { + newArguments, InfluxDbScope.start(queryInstrumenter(), parentContext, influxDbQuery) + }; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) @@ -109,7 +112,7 @@ public static void onExit( return; } - ((InfluxDbScope) enterArgs[1]).end(throwable); + ((InfluxDbScope) enterArgs[1]).end(throwable); } } @@ -117,7 +120,7 @@ public static void onExit( public static class InfluxDbModifyAdvice { @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) - public static InfluxDbScope onEnter( + public static InfluxDbScope onEnter( @Advice.Origin("#m") String methodName, @Advice.Argument(0) Object arg0, @Advice.FieldValue(value = "retrofit") Retrofit retrofit) { @@ -137,30 +140,33 @@ public static InfluxDbScope onEnter( (arg0 instanceof BatchPoints) ? ((BatchPoints) arg0).getDatabase() // write data by UDP protocol, in this way, can't get database name. - : arg0 instanceof Integer ? "" : String.valueOf(arg0); + : arg0 instanceof Integer ? null : String.valueOf(arg0); String operationName; if ("createDatabase".equals(methodName)) { + // createDatabase emits a CREATE DATABASE query. operationName = "CREATE DATABASE"; } else if ("deleteDatabase".equals(methodName)) { + // deleteDatabase emits a DROP DATABASE query. operationName = "DROP DATABASE"; } else { - operationName = "WRITE"; + operationName = methodName; } - InfluxDbRequest influxDbRequest = - InfluxDbRequest.create(httpUrl.host(), httpUrl.port(), database, operationName, null); + InfluxDbOperation influxDbOperation = + InfluxDbOperation.create(httpUrl.host(), httpUrl.port(), database, operationName); - if (!instrumenter().shouldStart(parentContext, influxDbRequest)) { + if (!requestInstrumenter().shouldStart(parentContext, influxDbOperation)) { return null; } - return InfluxDbScope.start(parentContext, influxDbRequest); + return InfluxDbScope.start(requestInstrumenter(), parentContext, influxDbOperation); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void onExit( - @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter @Nullable InfluxDbScope scope) { + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable InfluxDbScope scope) { CallDepth callDepth = CallDepth.forClass(InfluxDBImpl.class); if (callDepth.decrementAndGet() > 0 || scope == null) { return; diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbRequest.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbOperation.java similarity index 50% rename from instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbRequest.java rename to instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbOperation.java index c2a231340018..9a989c247aa5 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbRequest.java +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbOperation.java @@ -9,26 +9,20 @@ import javax.annotation.Nullable; @AutoValue -public abstract class InfluxDbRequest { - - public static InfluxDbRequest create( - String host, - int port, - String namespace, - @Nullable String operationName, - @Nullable String sql) { - return new AutoValue_InfluxDbRequest(host, port, namespace, operationName, sql); +public abstract class InfluxDbOperation { + + public static InfluxDbOperation create( + String host, int port, @Nullable String namespace, @Nullable String operation) { + return new AutoValue_InfluxDbOperation(host, port, namespace, operation); } public abstract String getHost(); public abstract int getPort(); - public abstract String getNamespace(); - @Nullable - public abstract String getOperationName(); + public abstract String getNamespace(); @Nullable - public abstract String getSql(); + public abstract String getOperation(); } diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQuery.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQuery.java new file mode 100644 index 000000000000..72fffd57cd5a --- /dev/null +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQuery.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.influxdb.v2_4; + +import com.google.auto.value.AutoValue; +import javax.annotation.Nullable; + +@AutoValue +public abstract class InfluxDbQuery { + + public static InfluxDbQuery create( + String host, int port, @Nullable String namespace, @Nullable String query) { + return new AutoValue_InfluxDbQuery(host, port, namespace, query); + } + + public abstract String getHost(); + + public abstract int getPort(); + + @Nullable + public abstract String getNamespace(); + + @Nullable + public abstract String getQuery(); +} diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQueryAttributesGetter.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQueryAttributesGetter.java new file mode 100644 index 000000000000..102e3c9deb46 --- /dev/null +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbQueryAttributesGetter.java @@ -0,0 +1,56 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.influxdb.v2_4; + +import static io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlDialect.DOUBLE_QUOTES_ARE_IDENTIFIERS; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + +import io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlClientAttributesGetter; +import io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlDialect; +import java.util.Collection; +import javax.annotation.Nullable; + +final class InfluxDbQueryAttributesGetter + implements SqlClientAttributesGetter { + + @Override + public Collection getRawQueryTexts(InfluxDbQuery request) { + String query = request.getQuery(); + if (query == null) { + return emptyList(); + } + return singletonList(query); + } + + @Override + public SqlDialect getSqlDialect(InfluxDbQuery request) { + // "String literals must be surrounded by single quotes." + // https://docs.influxdata.com/influxdb/v2/reference/syntax/influxql/spec/#strings + return DOUBLE_QUOTES_ARE_IDENTIFIERS; + } + + @Override + public String getDbSystemName(InfluxDbQuery request) { + return "influxdb"; + } + + @Nullable + @Override + public String getDbNamespace(InfluxDbQuery request) { + return request.getNamespace(); + } + + @Override + public String getServerAddress(InfluxDbQuery request) { + return request.getHost(); + } + + @Override + public Integer getServerPort(InfluxDbQuery request) { + return request.getPort(); + } +} diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbScope.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbScope.java index 4aed1fd4401e..a89e46605262 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbScope.java +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbScope.java @@ -5,32 +5,35 @@ package io.opentelemetry.javaagent.instrumentation.influxdb.v2_4; -import static io.opentelemetry.javaagent.instrumentation.influxdb.v2_4.InfluxDbSingletons.instrumenter; - import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import javax.annotation.Nullable; /** Container used to carry state between enter and exit advices */ -public class InfluxDbScope { - private final InfluxDbRequest influxDbRequest; +public class InfluxDbScope { + private final Instrumenter instrumenter; + private final REQUEST request; private final Context context; private final Scope scope; - private InfluxDbScope(InfluxDbRequest influxDbRequest, Context context, Scope scope) { - this.influxDbRequest = influxDbRequest; + private InfluxDbScope( + Instrumenter instrumenter, REQUEST request, Context context, Scope scope) { + this.instrumenter = instrumenter; + this.request = request; this.context = context; this.scope = scope; } - public static InfluxDbScope start(Context parentContext, InfluxDbRequest influxDbRequest) { - Context context = instrumenter().start(parentContext, influxDbRequest); - return new InfluxDbScope(influxDbRequest, context, context.makeCurrent()); + public static InfluxDbScope start( + Instrumenter instrumenter, Context parentContext, REQUEST request) { + Context context = instrumenter.start(parentContext, request); + return new InfluxDbScope<>(instrumenter, request, context, context.makeCurrent()); } public void end(@Nullable Throwable throwable) { scope.close(); - instrumenter().end(context, influxDbRequest, null, throwable); + instrumenter.end(context, request, null, throwable); } } diff --git a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbSingletons.java b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbSingletons.java index 0110c8f0eb6a..482fc078b6b7 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbSingletons.java +++ b/instrumentation/influxdb-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbSingletons.java @@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.api.incubator.semconv.db.internal.DbExceptionEventExtractors.setDbClientExceptionEventExtractor; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientMetrics; import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientSpanNameExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.db.SqlClientAttributesExtractor; @@ -18,28 +19,48 @@ @SuppressWarnings("deprecation") // to support old semconv public class InfluxDbSingletons { - private static final Instrumenter instrumenter; + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.influxdb-2.4"; + + private static final Instrumenter queryInstrumenter; + private static final Instrumenter requestInstrumenter; static { - InfluxDbAttributesGetter dbAttributesGetter = new InfluxDbAttributesGetter(); + InfluxDbQueryAttributesGetter queryAttributesGetter = new InfluxDbQueryAttributesGetter(); - InstrumenterBuilder builder = - Instrumenter.builder( + InstrumenterBuilder queryBuilder = + Instrumenter.builder( GlobalOpenTelemetry.get(), - "io.opentelemetry.influxdb-2.4", - DbClientSpanNameExtractor.createWithGenericOldSpanName(dbAttributesGetter)) + INSTRUMENTATION_NAME, + DbClientSpanNameExtractor.createWithGenericOldSpanName(queryAttributesGetter)) .addAttributesExtractor( - SqlClientAttributesExtractor.builder(dbAttributesGetter) + SqlClientAttributesExtractor.builder(queryAttributesGetter) .setTableAttribute(null) .build()) .addOperationMetrics(DbClientMetrics.get()); - setDbClientExceptionEventExtractor(builder); + setDbClientExceptionEventExtractor(queryBuilder); + + queryInstrumenter = queryBuilder.buildInstrumenter(SpanKindExtractor.alwaysClient()); + + InfluxDbAttributesGetter dbAttributesGetter = new InfluxDbAttributesGetter(); + + InstrumenterBuilder modifyBuilder = + Instrumenter.builder( + GlobalOpenTelemetry.get(), + INSTRUMENTATION_NAME, + DbClientSpanNameExtractor.create(dbAttributesGetter)) + .addAttributesExtractor(DbClientAttributesExtractor.create(dbAttributesGetter)) + .addOperationMetrics(DbClientMetrics.get()); + setDbClientExceptionEventExtractor(modifyBuilder); + + requestInstrumenter = modifyBuilder.buildInstrumenter(SpanKindExtractor.alwaysClient()); + } - instrumenter = builder.buildInstrumenter(SpanKindExtractor.alwaysClient()); + public static Instrumenter queryInstrumenter() { + return queryInstrumenter; } - public static Instrumenter instrumenter() { - return instrumenter; + public static Instrumenter requestInstrumenter() { + return requestInstrumenter; } private InfluxDbSingletons() {} diff --git a/instrumentation/influxdb-2.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClientTest.java b/instrumentation/influxdb-2.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClientTest.java index a990c18b613e..bec54faddc6f 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClientTest.java +++ b/instrumentation/influxdb-2.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClientTest.java @@ -123,14 +123,17 @@ void testQueryAndModifyWithOneArgument() { trace -> trace.hasSpansSatisfyingExactly( span -> - span.hasName("WRITE " + dbName) + span.hasName( + emitStableDatabaseSemconv() ? "write " + dbName : "WRITE " + dbName) .hasKind(SpanKind.CLIENT) .hasAttributesSatisfyingExactly( equalTo(maybeStable(DB_SYSTEM), INFLUXDB), equalTo(maybeStable(DB_NAME), dbName), equalTo(SERVER_ADDRESS, host), equalTo(SERVER_PORT, port), - equalTo(maybeStable(DB_OPERATION), "WRITE"))), + equalTo( + maybeStable(DB_OPERATION), + emitStableDatabaseSemconv() ? "write" : "WRITE"))), trace -> trace.hasSpansSatisfyingExactly( span -> @@ -370,14 +373,19 @@ void testWriteWithFourArguments() { trace -> trace.hasSpansSatisfyingExactly( span -> - span.hasName("WRITE " + DATABASE_NAME) + span.hasName( + emitStableDatabaseSemconv() + ? "write " + DATABASE_NAME + : "WRITE " + DATABASE_NAME) .hasKind(SpanKind.CLIENT) .hasAttributesSatisfyingExactly( equalTo(maybeStable(DB_SYSTEM), INFLUXDB), equalTo(maybeStable(DB_NAME), DATABASE_NAME), equalTo(SERVER_ADDRESS, host), equalTo(SERVER_PORT, port), - equalTo(maybeStable(DB_OPERATION), "WRITE")))); + equalTo( + maybeStable(DB_OPERATION), + emitStableDatabaseSemconv() ? "write" : "WRITE")))); } @Test @@ -391,14 +399,19 @@ void testWriteWithFiveArguments() { trace -> trace.hasSpansSatisfyingExactly( span -> - span.hasName("WRITE " + DATABASE_NAME) + span.hasName( + emitStableDatabaseSemconv() + ? "write " + DATABASE_NAME + : "WRITE " + DATABASE_NAME) .hasKind(SpanKind.CLIENT) .hasAttributesSatisfyingExactly( equalTo(maybeStable(DB_SYSTEM), INFLUXDB), equalTo(maybeStable(DB_NAME), DATABASE_NAME), equalTo(SERVER_ADDRESS, host), equalTo(SERVER_PORT, port), - equalTo(maybeStable(DB_OPERATION), "WRITE")))); + equalTo( + maybeStable(DB_OPERATION), + emitStableDatabaseSemconv() ? "write" : "WRITE")))); } @Test @@ -415,13 +428,15 @@ void testWriteWithUdp() { trace.hasSpansSatisfyingExactly( span -> span.hasName( - emitStableDatabaseSemconv() ? "WRITE " + host + ":" + port : "WRITE") + emitStableDatabaseSemconv() ? "write " + host + ":" + port : "WRITE") .hasKind(SpanKind.CLIENT) .hasAttributesSatisfyingExactly( equalTo(maybeStable(DB_SYSTEM), INFLUXDB), equalTo(maybeStable(DB_NAME), null), equalTo(SERVER_ADDRESS, host), equalTo(SERVER_PORT, port), - equalTo(maybeStable(DB_OPERATION), "WRITE")))); + equalTo( + maybeStable(DB_OPERATION), + emitStableDatabaseSemconv() ? "write" : "WRITE")))); } } diff --git a/instrumentation/influxdb-2.4/javaagent/src/test24/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClient24Test.java b/instrumentation/influxdb-2.4/javaagent/src/test24/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClient24Test.java index 0322dcacfada..ea81c8caa761 100644 --- a/instrumentation/influxdb-2.4/javaagent/src/test24/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClient24Test.java +++ b/instrumentation/influxdb-2.4/javaagent/src/test24/java/io/opentelemetry/javaagent/instrumentation/influxdb/v2_4/InfluxDbClient24Test.java @@ -113,14 +113,17 @@ void testQueryAndModifyWithOneArgument() { trace -> trace.hasSpansSatisfyingExactly( span -> - span.hasName("WRITE " + dbName) + span.hasName( + emitStableDatabaseSemconv() ? "write " + dbName : "WRITE " + dbName) .hasKind(SpanKind.CLIENT) .hasAttributesSatisfyingExactly( equalTo(maybeStable(DB_SYSTEM), INFLUXDB), equalTo(maybeStable(DB_NAME), dbName), equalTo(SERVER_ADDRESS, host), equalTo(SERVER_PORT, port), - equalTo(maybeStable(DB_OPERATION), "WRITE"))), + equalTo( + maybeStable(DB_OPERATION), + emitStableDatabaseSemconv() ? "write" : "WRITE"))), trace -> trace.hasSpansSatisfyingExactly( span ->