diff --git a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java index 2d913e0269..0f1613a136 100644 --- a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java +++ b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java @@ -15,6 +15,10 @@ package software.amazon.opentelemetry.javaagent.providers; +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_TEXT; +import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_ADDRESS; @@ -26,7 +30,6 @@ // 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 // They have been replaced with new keys: // https://github.com/open-telemetry/semantic-conventions-java/blob/release/v1.34.0/semconv/src/main/java/io/opentelemetry/semconv/DbAttributes.java#L77 -// TODO: Supporting new keys. Cannot do this now as new keys are not available in OTel Agent 2.11. // TODO: Delete deprecated keys once they no longer exist in binding version of the upstream code. import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_CONNECTION_STRING; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_NAME; @@ -93,6 +96,7 @@ import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_OPERATION; import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_REMOTE_OPERATION; import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.UNKNOWN_REMOTE_SERVICE; +import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.getKeyValueWithFallback; import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isAwsSDKSpan; import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isDBSpan; import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isKeyPresent; @@ -285,11 +289,12 @@ private static void setRemoteServiceAndOperation(SpanData span, AttributesBuilde remoteOperation = getRemoteOperation(span, RPC_METHOD); } else if (isDBSpan(span)) { - remoteService = getRemoteService(span, DB_SYSTEM); - if (isKeyPresent(span, DB_OPERATION)) { - remoteOperation = getRemoteOperation(span, DB_OPERATION); + remoteService = getRemoteServiceWithFallback(span, DB_SYSTEM_NAME, DB_SYSTEM); + if (isKeyPresentWithFallback(span, DB_OPERATION_NAME, DB_OPERATION)) { + remoteOperation = getRemoteOperationWithFallback(span, DB_OPERATION_NAME, DB_OPERATION); } else { - remoteOperation = getDBStatementRemoteOperation(span, DB_STATEMENT); + String dbStatement = getKeyValueWithFallback(span, DB_QUERY_TEXT, DB_STATEMENT); + remoteOperation = getDBStatementRemoteOperation(span, dbStatement); } } else if (isKeyPresent(span, FAAS_INVOKED_NAME) || isKeyPresent(span, FAAS_TRIGGER)) { remoteService = getRemoteService(span, FAAS_INVOKED_NAME); @@ -349,10 +354,7 @@ private static void setRemoteEnvironment(SpanData span, AttributesBuilder builde private static String generateRemoteOperation(SpanData span) { String remoteOperation = UNKNOWN_REMOTE_OPERATION; if (isKeyPresent(span, URL_FULL) || isKeyPresent(span, HTTP_URL)) { - String httpUrl = - isKeyPresent(span, URL_FULL) - ? span.getAttributes().get(URL_FULL) - : span.getAttributes().get(HTTP_URL); + String httpUrl = getKeyValueWithFallback(span, URL_FULL, HTTP_URL); try { URL url; if (httpUrl != null) { @@ -363,11 +365,8 @@ private static String generateRemoteOperation(SpanData span) { logger.log(Level.FINEST, "invalid http.url attribute: ", httpUrl); } } - if (isKeyPresent(span, HTTP_REQUEST_METHOD) || isKeyPresent(span, HTTP_METHOD)) { - String httpMethod = - isKeyPresent(span, HTTP_REQUEST_METHOD) - ? span.getAttributes().get(HTTP_REQUEST_METHOD) - : span.getAttributes().get(HTTP_METHOD); + if (isKeyPresentWithFallback(span, HTTP_REQUEST_METHOD, HTTP_METHOD)) { + String httpMethod = getKeyValueWithFallback(span, HTTP_REQUEST_METHOD, HTTP_METHOD); remoteOperation = httpMethod + " " + remoteOperation; } if (remoteOperation.equals(UNKNOWN_REMOTE_OPERATION)) { @@ -791,7 +790,7 @@ private static Optional getSnsResourceNameFromArn(Optional strin * provided. */ private static Optional getDbConnection(SpanData span) { - String dbName = span.getAttributes().get(DB_NAME); + String dbName = getKeyValueWithFallback(span, DB_NAMESPACE, DB_NAME); Optional dbConnection = Optional.empty(); if (isKeyPresent(span, SERVER_ADDRESS)) { @@ -949,6 +948,15 @@ private static String getRemoteService(SpanData span, AttributeKey remot return remoteService; } + static String getRemoteServiceWithFallback( + SpanData span, AttributeKey remoteSvcKey, AttributeKey remoteSvcFallbackKey) { + String remoteService = span.getAttributes().get(remoteSvcKey); + if (remoteService == null) { + return getRemoteService(span, remoteSvcFallbackKey); + } + return remoteService; + } + private static String getRemoteOperation(SpanData span, AttributeKey remoteOperationKey) { String remoteOperation = span.getAttributes().get(remoteOperationKey); if (remoteOperation == null) { @@ -972,9 +980,8 @@ static String getRemoteOperationWithFallback( * statement and compare to a regex list of known SQL keywords. The substring length is determined * by the longest known SQL keywords. */ - private static String getDBStatementRemoteOperation( - SpanData span, AttributeKey remoteOperationKey) { - String remoteOperation = span.getAttributes().get(remoteOperationKey); + private static String getDBStatementRemoteOperation(SpanData span, String dbStatement) { + String remoteOperation = dbStatement; if (remoteOperation == null) { remoteOperation = UNKNOWN_REMOTE_OPERATION; } diff --git a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanMetricsProcessor.java b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanMetricsProcessor.java index 9dabe2c3fb..c73e20e6dc 100644 --- a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanMetricsProcessor.java +++ b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanMetricsProcessor.java @@ -18,7 +18,7 @@ import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.incubating.HttpIncubatingAttributes.HTTP_STATUS_CODE; import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_SERVICE; -import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.isKeyPresent; +import static software.amazon.opentelemetry.javaagent.providers.AwsSpanProcessingUtil.getKeyValueWithFallback; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; @@ -152,12 +152,8 @@ public boolean isEndRequired() { // possible except for the throttle // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/awsxrayexporter/internal/translator/cause.go#L121-L160 private void recordErrorOrFault(SpanData spanData, Attributes attributes) { - Long httpStatusCode = null; - if (isKeyPresent(spanData, HTTP_RESPONSE_STATUS_CODE)) { - httpStatusCode = spanData.getAttributes().get(HTTP_RESPONSE_STATUS_CODE); - } else if (isKeyPresent(spanData, HTTP_STATUS_CODE)) { - httpStatusCode = spanData.getAttributes().get(HTTP_STATUS_CODE); - } + Long httpStatusCode = + getKeyValueWithFallback(spanData, HTTP_RESPONSE_STATUS_CODE, HTTP_STATUS_CODE); StatusCode statusCode = spanData.getStatus().getStatusCode(); if (httpStatusCode == null) { diff --git a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanProcessingUtil.java b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanProcessingUtil.java index 4da4d80e3d..ab92d050be 100644 --- a/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanProcessingUtil.java +++ b/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsSpanProcessingUtil.java @@ -15,6 +15,9 @@ package software.amazon.opentelemetry.javaagent.providers; +import static io.opentelemetry.semconv.DbAttributes.DB_OPERATION_NAME; +import static io.opentelemetry.semconv.DbAttributes.DB_QUERY_TEXT; +import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME; import static io.opentelemetry.semconv.UrlAttributes.URL_PATH; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; @@ -295,9 +298,9 @@ private static String generateIngressOperation(SpanData span) { // Check if the current Span adheres to database semantic conventions static boolean isDBSpan(SpanData span) { - return isKeyPresent(span, DB_SYSTEM) - || isKeyPresent(span, DB_OPERATION) - || isKeyPresent(span, DB_STATEMENT); + return isKeyPresentWithFallback(span, DB_SYSTEM_NAME, DB_SYSTEM) + || isKeyPresentWithFallback(span, DB_OPERATION_NAME, DB_OPERATION) + || isKeyPresentWithFallback(span, DB_QUERY_TEXT, DB_STATEMENT); } static boolean isLambdaServerSpan(ReadableSpan span) { diff --git a/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java b/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java index 81667f6313..e3d438e10f 100644 --- a/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java +++ b/awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java @@ -15,6 +15,7 @@ package software.amazon.opentelemetry.javaagent.providers; +import static io.opentelemetry.semconv.DbAttributes.DB_SYSTEM_NAME; import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD; import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE; import static io.opentelemetry.semconv.NetworkAttributes.NETWORK_PEER_ADDRESS; @@ -1792,4 +1793,34 @@ public void testBothMetricsWhenLocalRootConsumerProcess() { assertThat(attributeMap.get(SERVICE_METRIC)).isEqualTo(serviceAttributes); assertThat(attributeMap.get(DEPENDENCY_METRIC)).isEqualTo(dependencyAttributes); } + + @Test + public void testGetRemoteServiceWithFallback_PrimaryKeyPresent() { + mockAttribute(DB_SYSTEM_NAME, "mysql"); + mockAttribute(DB_SYSTEM, "postgresql"); + String result = + AwsMetricAttributeGenerator.getRemoteServiceWithFallback( + spanDataMock, DB_SYSTEM_NAME, DB_SYSTEM); + + assertThat(result).isEqualTo("mysql"); + } + + @Test + public void testGetRemoteServiceWithFallback_FallbackKeyPresent() { + mockAttribute(DB_SYSTEM, "postgresql"); + String result = + AwsMetricAttributeGenerator.getRemoteServiceWithFallback( + spanDataMock, DB_SYSTEM_NAME, DB_SYSTEM); + + assertThat(result).isEqualTo("postgresql"); + } + + @Test + public void testGetRemoteServiceWithFallback_BothKeysAbsent() { + String result = + AwsMetricAttributeGenerator.getRemoteServiceWithFallback( + spanDataMock, DB_SYSTEM_NAME, DB_SYSTEM); + + assertThat(result).isEqualTo(UNKNOWN_REMOTE_SERVICE); + } }