Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -99,6 +100,7 @@ static <REQUEST, RESPONSE> 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));
Expand All @@ -112,7 +114,7 @@ static <REQUEST, RESPONSE> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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()) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

/**
Expand All @@ -39,8 +44,15 @@ public final class SqlClientAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<REQUEST, RESPONSE>, SpanKeyProvider {

// copied from DbIncubatingAttributes
private static final AttributeKey<String> DB_NAME = AttributeKey.stringKey("db.name");
private static final AttributeKey<String> DB_SYSTEM = AttributeKey.stringKey("db.system");
private static final AttributeKey<String> DB_USER = AttributeKey.stringKey("db.user");
private static final AttributeKey<String> DB_CONNECTION_STRING =
AttributeKey.stringKey("db.connection_string");
private static final AttributeKey<String> DB_OPERATION = AttributeKey.stringKey("db.operation");
private static final AttributeKey<String> DB_STATEMENT = AttributeKey.stringKey("db.statement");
private static final AttributeKeyTemplate<String> DB_QUERY_PARAMETER =
AttributeKeyTemplate.stringKeyTemplate("db.query.parameter");

/** Creates the SQL client attributes extractor with default configuration. */
public static <REQUEST, RESPONSE> AttributesExtractor<REQUEST, RESPONSE> create(
Expand Down Expand Up @@ -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<String, String> queryParameters = getter.getDbQueryParameters(request);
if (queryParameters != null && !queryParameters.isEmpty()) {
for (Map.Entry<String, String> entry : queryParameters.entrySet()) {
attributes.put(DB_QUERY_PARAMETER.getAttributeKey(entry.getKey()), entry.getValue());
}
}
}
serverAttributesExtractor.onStart(attributes, parentContext, request);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ public SqlClientAttributesExtractorBuilder<REQUEST, RESPONSE> 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}.
*
* <p>For most instrumentations, enabling this will produce invalid semantic conventions.
* <p>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<REQUEST, RESPONSE> setSingleOperationAndCollection(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -23,33 +22,65 @@ public interface SqlClientAttributesGetter<REQUEST, RESPONSE>
extends DbClientAttributesGetter<REQUEST, RESPONSE> {

/**
* 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.
*
* <p>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.
*
* <p>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.
*
* <p>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.
*
* <p>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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -50,6 +51,11 @@ public String getDbNamespace(Map<String, String> map) {
return map.get("db.namespace");
}

@Override
public String getDbCollectionName(Map<String, String> map) {
return map.get("db.collection.name");
}

@Deprecated
@Override
public String getConnectionString(Map<String, String> map) {
Expand All @@ -71,6 +77,12 @@ public String getDbQuerySummary(Map<String, String> map) {
public String getDbOperationName(Map<String, String> map) {
return map.get("db.operation.name");
}

@Deprecated
@Override
public String getDbOperation(Map<String, String> map) {
return map.get("db.operation");
}
}

@SuppressWarnings("deprecation") // TODO DB_CONNECTION_STRING deprecation
Expand All @@ -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();
Expand All @@ -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"),
Expand All @@ -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"),
Expand Down
Loading
Loading