Skip to content

Commit 9e4f05c

Browse files
lukeina2zthpierce
andauthored
[semconv]: Add support for new formal DB semantic convention keys (#1162)
ADOT Java currently uses some deprecated incubating semconv keys. This PR adds support for the newly introduced formal semconv keys that replace them, while maintaining backward compatibility by falling back to the legacy keys when necessary. **Deprecated keys:** - DB_NAME - DB_OPERATION - DB_STATEMENT - DB_SYSTEM (Reference: https://github.com/open-telemetry/semantic-conventions-java/blob/release/v1.34.0/semconv-incubating/src/main/java/io/opentelemetry/semconv/incubating/DbIncubatingAttributes.java#L322-L327) **New keys:** - DB_NAMESPACE - DB_OPERATION_NAME - DB_QUERY_TEXT - DB_SYSTEM_NAME **Tests performed:** - Unit tests: `./gradlew build test` - Smoke/contract tests: `./gradlew appsignals-tests:contract-tests:contractTests` - Manual E2E test with SpringBoot sample app. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Thomas Pierce <thp@amazon.com>
1 parent 2db2590 commit 9e4f05c

File tree

5 files changed

+188
-30
lines changed

5 files changed

+188
-30
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ If your change does not need a CHANGELOG entry, add the "skip changelog" label t
1818
- Support X-Ray Trace Id extraction from Lambda Context object, and respect user-configured OTEL_PROPAGATORS in AWS Lamdba instrumentation
1919
([#1191](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1191)) ([#1218](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1218))
2020
- Adaptive Sampling improvements: Ensure propagation of sampling rule across services and AWS accounts. Remove unnecessary B3 propagator.
21-
([#1201](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1201))
21+
([#1201](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1201))
22+
- Add support for new formal database semantic convention keys.
23+
([#1162](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1162))

awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
package software.amazon.opentelemetry.javaagent.providers;
1717

18+
import static io.opentelemetry.semconv.DbAttributes.DB_NAMESPACE;
19+
import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME;
20+
import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_TEXT;
21+
import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME;
1822
import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
1923
import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
2024
import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_ADDRESS;
@@ -26,7 +30,6 @@
2630
// https://github.com/open-telemetry/semantic-conventions-java/blob/release/v1.34.0/semconv-incubating/src/main/java/io/opentelemetry/semconv/incubating/DbIncubatingAttributes.java#L322-L327
2731
// They have been replaced with new keys:
2832
// https://github.com/open-telemetry/semantic-conventions-java/blob/release/v1.34.0/semconv/src/main/java/io/opentelemetry/semconv/DbAttributes.java#L77
29-
// TODO: Supporting new keys. Cannot do this now as new keys are not available in OTel Agent 2.11.
3033
// TODO: Delete deprecated keys once they no longer exist in binding version of the upstream code.
3134
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_CONNECTION_STRING;
3235
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME;
@@ -93,6 +96,7 @@
9396
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_OPERATION;
9497
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_REMOTE_OPERATION;
9598
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_REMOTE_SERVICE;
99+
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.getKeyValueWithFallback;
96100
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isAwsSDKSpan;
97101
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isDBSpan;
98102
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isKeyPresent;
@@ -285,11 +289,12 @@ private static void setRemoteServiceAndOperation(SpanData span, AttributesBuilde
285289
remoteOperation = getRemoteOperation(span, RPC_METHOD);
286290

287291
} else if (isDBSpan(span)) {
288-
remoteService = getRemoteService(span, DB_SYSTEM);
289-
if (isKeyPresent(span, DB_OPERATION)) {
290-
remoteOperation = getRemoteOperation(span, DB_OPERATION);
292+
remoteService = getRemoteServiceWithFallback(span, DB_SYSTEM_NAME, DB_SYSTEM);
293+
if (isKeyPresentWithFallback(span, DB_OPERATION_NAME, DB_OPERATION)) {
294+
remoteOperation = getRemoteOperationWithFallback(span, DB_OPERATION_NAME, DB_OPERATION);
291295
} else {
292-
remoteOperation = getDBStatementRemoteOperation(span, DB_STATEMENT);
296+
String dbStatement = getKeyValueWithFallback(span, DB_QUERY_TEXT, DB_STATEMENT);
297+
remoteOperation = getDBStatementRemoteOperation(span, dbStatement);
293298
}
294299
} else if (isKeyPresent(span, FAAS_INVOKED_NAME) || isKeyPresent(span, FAAS_TRIGGER)) {
295300
remoteService = getRemoteService(span, FAAS_INVOKED_NAME);
@@ -348,11 +353,8 @@ private static void setRemoteEnvironment(SpanData span, AttributesBuilder builde
348353
*/
349354
private static String generateRemoteOperation(SpanData span) {
350355
String remoteOperation = UNKNOWN_REMOTE_OPERATION;
351-
if (isKeyPresent(span, URL_FULL) || isKeyPresent(span, HTTP_URL)) {
352-
String httpUrl =
353-
isKeyPresent(span, URL_FULL)
354-
? span.getAttributes().get(URL_FULL)
355-
: span.getAttributes().get(HTTP_URL);
356+
if (isKeyPresentWithFallback(span, URL_FULL, HTTP_URL)) {
357+
String httpUrl = getKeyValueWithFallback(span, URL_FULL, HTTP_URL);
356358
try {
357359
URL url;
358360
if (httpUrl != null) {
@@ -363,11 +365,8 @@ private static String generateRemoteOperation(SpanData span) {
363365
logger.log(Level.FINEST, "invalid http.url attribute: ", httpUrl);
364366
}
365367
}
366-
if (isKeyPresent(span, HTTP_REQUEST_METHOD) || isKeyPresent(span, HTTP_METHOD)) {
367-
String httpMethod =
368-
isKeyPresent(span, HTTP_REQUEST_METHOD)
369-
? span.getAttributes().get(HTTP_REQUEST_METHOD)
370-
: span.getAttributes().get(HTTP_METHOD);
368+
if (isKeyPresentWithFallback(span, HTTP_REQUEST_METHOD, HTTP_METHOD)) {
369+
String httpMethod = getKeyValueWithFallback(span, HTTP_REQUEST_METHOD, HTTP_METHOD);
371370
remoteOperation = httpMethod + " " + remoteOperation;
372371
}
373372
if (remoteOperation.equals(UNKNOWN_REMOTE_OPERATION)) {
@@ -791,7 +790,7 @@ private static Optional<String> getSnsResourceNameFromArn(Optional<String> strin
791790
* provided.
792791
*/
793792
private static Optional<String> getDbConnection(SpanData span) {
794-
String dbName = span.getAttributes().get(DB_NAME);
793+
String dbName = getKeyValueWithFallback(span, DB_NAMESPACE, DB_NAME);
795794
Optional<String> dbConnection = Optional.empty();
796795

797796
if (isKeyPresent(span, SERVER_ADDRESS)) {
@@ -949,6 +948,17 @@ private static String getRemoteService(SpanData span, AttributeKey<String> remot
949948
return remoteService;
950949
}
951950

951+
static String getRemoteServiceWithFallback(
952+
SpanData span,
953+
AttributeKey<String> remoteServiceKey,
954+
AttributeKey<String> remoteServiceFallbackKey) {
955+
String remoteService = span.getAttributes().get(remoteServiceKey);
956+
if (remoteService == null) {
957+
return getRemoteService(span, remoteServiceFallbackKey);
958+
}
959+
return remoteService;
960+
}
961+
952962
private static String getRemoteOperation(SpanData span, AttributeKey<String> remoteOperationKey) {
953963
String remoteOperation = span.getAttributes().get(remoteOperationKey);
954964
if (remoteOperation == null) {
@@ -972,9 +982,8 @@ static String getRemoteOperationWithFallback(
972982
* statement and compare to a regex list of known SQL keywords. The substring length is determined
973983
* by the longest known SQL keywords.
974984
*/
975-
private static String getDBStatementRemoteOperation(
976-
SpanData span, AttributeKey<String> remoteOperationKey) {
977-
String remoteOperation = span.getAttributes().get(remoteOperationKey);
985+
private static String getDBStatementRemoteOperation(SpanData span, String dbStatement) {
986+
String remoteOperation = dbStatement;
978987
if (remoteOperation == null) {
979988
remoteOperation = UNKNOWN_REMOTE_OPERATION;
980989
}

awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanMetricsProcessor.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
1919
import static io.opentelemetry.semconv.incubating.HttpIncubatingAttributes.HTTP_STATUS_CODE;
2020
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_SERVICE;
21-
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isKeyPresent;
21+
import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.getKeyValueWithFallback;
2222

2323
import io.opentelemetry.api.common.Attributes;
2424
import io.opentelemetry.api.metrics.DoubleHistogram;
@@ -152,12 +152,8 @@ public boolean isEndRequired() {
152152
// possible except for the throttle
153153
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/awsxrayexporter/internal/translator/cause.go#L121-L160
154154
private void recordErrorOrFault(SpanData spanData, Attributes attributes) {
155-
Long httpStatusCode = null;
156-
if (isKeyPresent(spanData, HTTP_RESPONSE_STATUS_CODE)) {
157-
httpStatusCode = spanData.getAttributes().get(HTTP_RESPONSE_STATUS_CODE);
158-
} else if (isKeyPresent(spanData, HTTP_STATUS_CODE)) {
159-
httpStatusCode = spanData.getAttributes().get(HTTP_STATUS_CODE);
160-
}
155+
Long httpStatusCode =
156+
getKeyValueWithFallback(spanData, HTTP_RESPONSE_STATUS_CODE, HTTP_STATUS_CODE);
161157
StatusCode statusCode = spanData.getStatus().getStatusCode();
162158

163159
if (httpStatusCode == null) {

awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanProcessingUtil.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
package software.amazon.opentelemetry.javaagent.providers;
1717

18+
import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME;
19+
import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_TEXT;
20+
import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME;
1821
import static io.opentelemetry.semconv.UrlAttributes.URL_PATH;
1922
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
2023
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT;
@@ -295,9 +298,9 @@ private static String generateIngressOperation(SpanData span) {
295298

296299
// Check if the current Span adheres to database semantic conventions
297300
static boolean isDBSpan(SpanData span) {
298-
return isKeyPresent(span, DB_SYSTEM)
299-
|| isKeyPresent(span, DB_OPERATION)
300-
|| isKeyPresent(span, DB_STATEMENT);
301+
return isKeyPresentWithFallback(span, DB_SYSTEM_NAME, DB_SYSTEM)
302+
|| isKeyPresentWithFallback(span, DB_OPERATION_NAME, DB_OPERATION)
303+
|| isKeyPresentWithFallback(span, DB_QUERY_TEXT, DB_STATEMENT);
301304
}
302305

303306
static boolean isLambdaServerSpan(ReadableSpan span) {

0 commit comments

Comments
 (0)