Skip to content

Commit d5ad8f5

Browse files
authored
Merge pull request #818 from ektabj/main
Adding data base user attribute in EMF logs
2 parents 5cc5861 + 6f63a07 commit d5ad8f5

File tree

5 files changed

+78
-3
lines changed

5 files changed

+78
-3
lines changed

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/jdbc/JdbcContractTestBase.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ protected void assertAwsSpanAttributes(
5353
String path,
5454
String dbSystem,
5555
String dbOperation,
56+
String dbUser,
5657
String type,
5758
String identifier) {
5859
assertThat(resourceScopeSpans)
@@ -61,7 +62,7 @@ protected void assertAwsSpanAttributes(
6162
assertThat(rss.getSpan().getKind()).isEqualTo(SPAN_KIND_CLIENT);
6263
var attributesList = rss.getSpan().getAttributesList();
6364
assertAwsAttributes(
64-
attributesList, method, path, dbSystem, dbOperation, type, identifier);
65+
attributesList, method, path, dbSystem, dbOperation, dbUser, type, identifier);
6566
});
6667
}
6768

@@ -71,6 +72,7 @@ protected void assertAwsAttributes(
7172
String endpoint,
7273
String dbSystem,
7374
String dbOperation,
75+
String dbUser,
7476
String type,
7577
String identifier) {
7678
var assertions =
@@ -98,6 +100,11 @@ protected void assertAwsAttributes(
98100
.isEqualTo(AppSignalsConstants.AWS_REMOTE_OPERATION);
99101
assertThat(attribute.getValue().getStringValue()).isEqualTo(dbOperation);
100102
})
103+
.satisfiesOnlyOnce(
104+
attribute -> {
105+
assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_REMOTE_DB_USER);
106+
assertThat(attribute.getValue().getStringValue()).isEqualTo(dbUser);
107+
})
101108
.satisfiesOnlyOnce(
102109
attribute -> {
103110
assertThat(attribute.getKey()).isEqualTo(AppSignalsConstants.AWS_SPAN_KIND);
@@ -327,7 +334,7 @@ protected void assertSuccess(
327334
assertThat(response.status().isSuccess()).isTrue();
328335

329336
var traces = mockCollectorClient.getTraces();
330-
assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, type, identifier);
337+
assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, dbUser, type, identifier);
331338
assertSemanticConventionsSpanAttributes(
332339
traces, otelStatusCode, dbSqlTable, dbSystem, dbOperation, dbUser, dbName, jdbcUrl);
333340

@@ -385,7 +392,7 @@ protected void assertFault(
385392
assertThat(response.status().isServerError()).isTrue();
386393

387394
var traces = mockCollectorClient.getTraces();
388-
assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, type, identifier);
395+
assertAwsSpanAttributes(traces, method, path, dbSystem, dbOperation, dbUser, type, identifier);
389396
assertSemanticConventionsSpanAttributes(
390397
traces, otelStatusCode, dbSqlTable, dbSystem, dbOperation, dbUser, dbName, jdbcUrl);
391398

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/AppSignalsConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ public class AppSignalsConstants {
3232
public static final String AWS_REMOTE_RESOURCE_TYPE = "aws.remote.resource.type";
3333
public static final String AWS_REMOTE_RESOURCE_IDENTIFIER = "aws.remote.resource.identifier";
3434
public static final String AWS_SPAN_KIND = "aws.span.kind";
35+
public static final String AWS_REMOTE_DB_USER = "aws.remote.db.user";
3536
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ private AwsAttributeKeys() {}
4141
static final AttributeKey<String> AWS_REMOTE_RESOURCE_TYPE =
4242
AttributeKey.stringKey("aws.remote.resource.type");
4343

44+
static final AttributeKey<String> AWS_REMOTE_DB_USER =
45+
AttributeKey.stringKey("aws.remote.db.user");
46+
4447
static final AttributeKey<String> AWS_SDK_DESCENDANT =
4548
AttributeKey.stringKey("aws.sdk.descendant");
4649

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static io.opentelemetry.semconv.SemanticAttributes.DB_OPERATION;
2222
import static io.opentelemetry.semconv.SemanticAttributes.DB_STATEMENT;
2323
import static io.opentelemetry.semconv.SemanticAttributes.DB_SYSTEM;
24+
import static io.opentelemetry.semconv.SemanticAttributes.DB_USER;
2425
import static io.opentelemetry.semconv.SemanticAttributes.FAAS_INVOKED_NAME;
2526
import static io.opentelemetry.semconv.SemanticAttributes.FAAS_TRIGGER;
2627
import static io.opentelemetry.semconv.SemanticAttributes.GRAPHQL_OPERATION_TYPE;
@@ -45,6 +46,7 @@
4546
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LOCAL_SERVICE;
4647
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_NAME;
4748
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_URL;
49+
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_DB_USER;
4850
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_OPERATION;
4951
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_IDENTIFIER;
5052
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_TYPE;
@@ -151,6 +153,7 @@ private Attributes generateDependencyMetricAttributes(SpanData span, Resource re
151153
setRemoteResourceTypeAndIdentifier(span, builder);
152154
setSpanKindForDependency(span, builder);
153155
setHttpStatus(span, builder);
156+
setRemoteDbUser(span, builder);
154157

155158
return builder.build();
156159
}
@@ -526,6 +529,12 @@ private static void setHttpStatus(SpanData span, AttributesBuilder builder) {
526529
}
527530
}
528531

532+
private static void setRemoteDbUser(SpanData span, AttributesBuilder builder) {
533+
if (isDBSpan(span) && isKeyPresent(span, DB_USER)) {
534+
builder.put(AWS_REMOTE_DB_USER, span.getAttributes().get(DB_USER));
535+
}
536+
}
537+
529538
/**
530539
* Attempt to pull status code from spans produced by AWS SDK instrumentation (both v1 and v2).
531540
* AWS SDK instrumentation does not populate http.status_code when non-200 status codes are

awsagentprovider/src/test/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGeneratorTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LOCAL_SERVICE;
2727
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_NAME;
2828
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_URL;
29+
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_DB_USER;
2930
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_OPERATION;
3031
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_IDENTIFIER;
3132
import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_TYPE;
@@ -1029,6 +1030,60 @@ private void validateHttpStatusForNonLocalRootWithThrowableForClient(
10291030
}
10301031
}
10311032

1033+
@Test
1034+
public void testDBUserAttribute() {
1035+
mockAttribute(DB_OPERATION, "db_operation");
1036+
mockAttribute(DB_USER, "db_user");
1037+
when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT);
1038+
1039+
Attributes actualAttributes =
1040+
GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC);
1041+
assertThat(actualAttributes.get(AWS_REMOTE_OPERATION)).isEqualTo("db_operation");
1042+
assertThat(actualAttributes.get(AWS_REMOTE_DB_USER)).isEqualTo("db_user");
1043+
}
1044+
1045+
@Test
1046+
public void testDBUserAttributeAbsent() {
1047+
mockAttribute(DB_SYSTEM, "db_system");
1048+
when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT);
1049+
1050+
Attributes actualAttributes =
1051+
GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC);
1052+
assertThat(actualAttributes.get(AWS_REMOTE_DB_USER)).isNull();
1053+
}
1054+
1055+
@Test
1056+
public void testDBUserAttributeWithDifferentValues() {
1057+
mockAttribute(DB_OPERATION, "db_operation");
1058+
mockAttribute(DB_USER, "non_db_user");
1059+
when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT);
1060+
1061+
Attributes actualAttributes =
1062+
GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC);
1063+
assertThat(actualAttributes.get(AWS_REMOTE_DB_USER)).isEqualTo("non_db_user");
1064+
}
1065+
1066+
@Test
1067+
public void testDBUserAttributeNotPresentInServiceMetricForServerSpan() {
1068+
mockAttribute(DB_USER, "db_user");
1069+
mockAttribute(DB_SYSTEM, "db_system");
1070+
when(spanDataMock.getKind()).thenReturn(SpanKind.SERVER);
1071+
1072+
Attributes actualAttributes =
1073+
GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(SERVICE_METRIC);
1074+
assertThat(actualAttributes.get(AWS_REMOTE_DB_USER)).isNull();
1075+
}
1076+
1077+
@Test
1078+
public void testDbUserPresentAndIsDbSpanFalse() {
1079+
mockAttribute(DB_USER, "DB user");
1080+
when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT);
1081+
1082+
Attributes actualAttributes =
1083+
GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC);
1084+
assertThat(actualAttributes.get(AWS_REMOTE_DB_USER)).isNull();
1085+
}
1086+
10321087
@Test
10331088
public void testNormalizeRemoteServiceName_NoNormalization() {
10341089
String serviceName = "non aws service";

0 commit comments

Comments
 (0)