Skip to content

Commit 2d28a85

Browse files
add inject datadog attribute config (#9943)
* add config to disable injecting datadog attribute in aws messaging services * add checks to messageAttributeInjectors * separate config for each aws service * tests * add configs to supported configurations file * update supported-configurations with DD_TRACE env configs * apply pr suggestions * add new configs to toString
1 parent 7dee697 commit 2d28a85

File tree

18 files changed

+282
-33
lines changed

18 files changed

+282
-33
lines changed

dd-java-agent/instrumentation/aws-java/aws-java-eventbridge-2.0/src/main/java/datadog/trace/instrumentation/aws/v2/eventbridge/EventBridgeInterceptor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import static datadog.trace.instrumentation.aws.v2.eventbridge.TextMapInjectAdapter.SETTER;
77

88
import datadog.context.Context;
9+
import datadog.trace.api.Config;
910
import datadog.trace.api.datastreams.DataStreamsContext;
1011
import datadog.trace.api.datastreams.DataStreamsTags;
1112
import datadog.trace.api.datastreams.PathwayContext;
@@ -34,7 +35,8 @@ public class EventBridgeInterceptor implements ExecutionInterceptor {
3435

3536
@Override
3637
public SdkRequest modifyRequest(ModifyRequest context, ExecutionAttributes executionAttributes) {
37-
if (!(context.request() instanceof PutEventsRequest)) {
38+
if (!(context.request() instanceof PutEventsRequest)
39+
|| !Config.get().isEventbridgeInjectDatadogAttributeEnabled()) {
3840
return context.request();
3941
}
4042

dd-java-agent/instrumentation/aws-java/aws-java-eventbridge-2.0/src/test/groovy/EventBridgeClientTest.groovy

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import datadog.trace.agent.test.InstrumentationSpecification
22
import datadog.trace.api.DDSpanTypes
33
import datadog.trace.api.config.GeneralConfig
44
import groovy.json.JsonSlurper
5+
import java.time.Duration
6+
import java.util.concurrent.CompletableFuture
57
import org.testcontainers.containers.GenericContainer
68
import org.testcontainers.utility.DockerImageName
79
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
@@ -17,9 +19,6 @@ import software.amazon.awssdk.services.sqs.SqsClient
1719
import software.amazon.awssdk.services.sqs.model.QueueAttributeName
1820
import spock.lang.Shared
1921

20-
import java.time.Duration
21-
import java.util.concurrent.CompletableFuture
22-
2322
class EventBridgeClientTest extends InstrumentationSpecification {
2423
static final LOCALSTACK = new GenericContainer(DockerImageName.parse("localstack/localstack:4.2.0"))
2524
.withExposedPorts(4566)
@@ -495,4 +494,31 @@ class EventBridgeClientTest extends InstrumentationSpecification {
495494
'tracestate'
496495
]
497496
}
497+
498+
def "datadog context is not injected when eventbridgeInjectDatadogAttribute is disabled"() {
499+
setup:
500+
injectSysConfig("eventbridge.inject.datadog.attribute.enabled", "false")
501+
502+
when:
503+
TEST_WRITER.clear()
504+
eventBridgeClient.putEvents { req ->
505+
req.entries(
506+
PutEventsRequestEntry.builder()
507+
.source("com.example")
508+
.detailType("test-no-inject")
509+
.detail('{"message":"no-inject"}')
510+
.eventBusName(testBusARN)
511+
.build()
512+
)
513+
}
514+
515+
def message = sqsClient.receiveMessage { it.queueUrl(testQueueURL).waitTimeSeconds(3) }.messages().get(0)
516+
def messageBody = new JsonSlurper().parseText(message.body())
517+
518+
then:
519+
def detail = messageBody["detail"]
520+
assert detail instanceof Map
521+
assert detail["message"] == "no-inject"
522+
assert detail["_datadog"] == null
523+
}
498524
}

dd-java-agent/instrumentation/aws-java/aws-java-sfn-2.0/src/main/java/datadog/trace/instrumentation/aws/v2/sfn/SfnInterceptor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static datadog.trace.bootstrap.instrumentation.api.AgentSpan.fromContext;
44

55
import datadog.context.Context;
6+
import datadog.trace.api.Config;
67
import datadog.trace.bootstrap.InstanceStore;
78
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
89
import software.amazon.awssdk.core.SdkRequest;
@@ -23,10 +24,14 @@ public SfnInterceptor() {}
2324

2425
@Override
2526
public SdkRequest modifyRequest(ModifyRequest context, ExecutionAttributes executionAttributes) {
27+
SdkRequest request = context.request();
28+
if (!Config.get().isSfnInjectDatadogAttributeEnabled()) {
29+
return request;
30+
}
2631
try {
2732
return modifyRequestImpl(context, executionAttributes);
2833
} catch (Exception e) {
29-
return context.request();
34+
return request;
3035
}
3136
}
3237

dd-java-agent/instrumentation/aws-java/aws-java-sfn-2.0/src/test/groovy/SfnClientTest.groovy

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1+
import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
2+
13
import datadog.trace.agent.test.naming.VersionedNamingTestBase
24
import datadog.trace.agent.test.utils.TraceUtils
35
import datadog.trace.api.DDSpanTypes
46
import datadog.trace.bootstrap.instrumentation.api.Tags
57
import groovy.json.JsonSlurper
8+
import java.time.Duration
69
import org.testcontainers.containers.GenericContainer
710
import org.testcontainers.utility.DockerImageName
11+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
12+
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
13+
import software.amazon.awssdk.regions.Region
814
import software.amazon.awssdk.services.sfn.SfnClient
915
import software.amazon.awssdk.services.sfn.model.SfnException
1016
import software.amazon.awssdk.services.sfn.model.StartExecutionResponse
11-
import software.amazon.awssdk.regions.Region
12-
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
13-
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
1417
import spock.lang.Shared
1518

16-
import java.time.Duration
17-
18-
import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
19-
20-
2119
abstract class SfnClientTest extends VersionedNamingTestBase {
2220
@Shared GenericContainer localStack
2321
@Shared SfnClient sfnClient
@@ -117,6 +115,28 @@ abstract class SfnClientTest extends VersionedNamingTestBase {
117115
input["_datadog"]["x-datadog-tags"] != null
118116
}
119117

118+
def "datadog context is not injected when SfnInjectDatadogAttribute is disabled"() {
119+
setup:
120+
injectSysConfig("sfn.inject.datadog.attribute.enabled", "false")
121+
122+
when:
123+
StartExecutionResponse response = sfnClient.startExecution { builder ->
124+
builder.stateMachineArn(testStateMachineARN)
125+
.input("{\"key\": \"value\"}")
126+
.build()
127+
}
128+
129+
then:
130+
def execution = sfnClient.describeExecution { builder ->
131+
builder.executionArn(response.executionArn())
132+
.build()
133+
}
134+
135+
def input = new JsonSlurper().parseText(execution.input())
136+
assert input["key"] == "value"
137+
assert input["_datadog"] == null
138+
}
139+
120140
def "AWS rejects invalid JSON but instrumentation does not error"() {
121141
when:
122142
sfnClient.startExecution { b ->

dd-java-agent/instrumentation/aws-java/aws-java-sns-1.0/src/main/java/datadog/trace/instrumentation/aws/v1/sns/SnsInterceptor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.amazonaws.services.sns.model.PublishBatchRequestEntry;
1414
import com.amazonaws.services.sns.model.PublishRequest;
1515
import datadog.context.Context;
16+
import datadog.trace.api.Config;
1617
import datadog.trace.api.datastreams.DataStreamsContext;
1718
import datadog.trace.api.datastreams.DataStreamsTags;
1819
import datadog.trace.bootstrap.ContextStore;
@@ -49,6 +50,9 @@ private ByteBuffer getMessageAttributeValueToInject(
4950

5051
@Override
5152
public AmazonWebServiceRequest beforeMarshalling(AmazonWebServiceRequest request) {
53+
if (!Config.get().isSnsInjectDatadogAttributeEnabled()) {
54+
return request;
55+
}
5256
// Injecting the trace context into SNS messageAttributes.
5357
if (request instanceof PublishRequest) {
5458
PublishRequest pRequest = (PublishRequest) request;

dd-java-agent/instrumentation/aws-java/aws-java-sns-1.0/src/test/groovy/SnsClientTest.groovy

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import datadog.trace.api.config.GeneralConfig
1313
import datadog.trace.bootstrap.instrumentation.api.Tags
1414
import datadog.trace.core.datastreams.StatsGroup
1515
import groovy.json.JsonSlurper
16+
import java.time.Duration
1617
import org.testcontainers.containers.GenericContainer
1718
import org.testcontainers.utility.DockerImageName
1819
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
@@ -22,9 +23,6 @@ import software.amazon.awssdk.services.sqs.SqsClient
2223
import software.amazon.awssdk.services.sqs.model.QueueAttributeName
2324
import spock.lang.Shared
2425

25-
import java.time.Duration
26-
27-
2826
abstract class SnsClientTest extends VersionedNamingTestBase {
2927

3028
static final LOCALSTACK = new GenericContainer(DockerImageName.parse("localstack/localstack:4.2.0"))
@@ -210,6 +208,26 @@ abstract class SnsClientTest extends VersionedNamingTestBase {
210208
!traceContextInJson['dd-pathway-ctx-base64'].toString().isBlank()
211209
}
212210

211+
212+
def "datadog context is not injected when SnsInjectDatadogAttribute is disabled"() {
213+
setup:
214+
TEST_WRITER.clear()
215+
injectSysConfig("sns.inject.datadog.attribute.enabled", "false")
216+
217+
when:
218+
snsClient.publish(testTopicARN, 'sometext')
219+
220+
def message = sqsClient.receiveMessage { it.queueUrl(testQueueURL).waitTimeSeconds(3) }.messages().get(0)
221+
def jsonSlurper = new JsonSlurper()
222+
def messageBody = jsonSlurper.parseText(message.body())
223+
if (isDataStreamsEnabled()) {
224+
TEST_DATA_STREAMS_WRITER.waitForGroups(1)
225+
}
226+
then:
227+
assert messageBody["Message"] == "sometext"
228+
assert messageBody["MessageAttributes"] == null
229+
}
230+
213231
def "SNS message to phone number doesn't leak exception"() {
214232
when:
215233
snsClient.publish(new PublishRequest().withPhoneNumber("+19995550123").withMessage('sometext'))

dd-java-agent/instrumentation/aws-java/aws-java-sns-2.0/src/main/java/datadog/trace/instrumentation/aws/v2/sns/SnsInterceptor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import static datadog.trace.instrumentation.aws.v2.sns.TextMapInjectAdapter.SETTER;
88

99
import datadog.context.Context;
10+
import datadog.trace.api.Config;
1011
import datadog.trace.api.datastreams.DataStreamsContext;
1112
import datadog.trace.api.datastreams.DataStreamsTags;
1213
import datadog.trace.bootstrap.InstanceStore;
@@ -50,6 +51,9 @@ public SnsInterceptor() {}
5051

5152
@Override
5253
public SdkRequest modifyRequest(ModifyRequest context, ExecutionAttributes executionAttributes) {
54+
if (!Config.get().isSnsInjectDatadogAttributeEnabled()) {
55+
return context.request();
56+
}
5357
// Injecting the trace context into SNS messageAttributes.
5458
if (context.request() instanceof PublishRequest) {
5559
PublishRequest request = (PublishRequest) context.request();

dd-java-agent/instrumentation/aws-java/aws-java-sns-2.0/src/test/groovy/SnsClientTest.groovy

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,25 @@ abstract class SnsClientTest extends VersionedNamingTestBase {
180180
!traceContextInJson['dd-pathway-ctx-base64'].toString().isBlank()
181181
}
182182

183+
def "datadog context is not injected when SnsInjectDatadogAttribute is disabled"() {
184+
setup:
185+
TEST_WRITER.clear()
186+
injectSysConfig("sns.inject.datadog.attribute.enabled", "false")
187+
188+
when:
189+
snsClient.publish { it.message("sometext").topicArn(testTopicARN)}
190+
191+
def message = sqsClient.receiveMessage { it.queueUrl(testQueueURL).waitTimeSeconds(3) }.messages().get(0)
192+
def jsonSlurper = new JsonSlurper()
193+
def messageBody = jsonSlurper.parseText(message.body())
194+
if (isDataStreamsEnabled()) {
195+
TEST_DATA_STREAMS_WRITER.waitForGroups(1)
196+
}
197+
then:
198+
assert messageBody["Message"] == "sometext"
199+
assert messageBody["MessageAttributes"] == null
200+
}
201+
183202
def "SNS message to phone number doesn't leak exception"() {
184203
when:
185204
snsClient.publish { it.message("sometext").phoneNumber("+19995550123") }

dd-java-agent/instrumentation/aws-java/aws-java-sqs-1.0/src/main/java/datadog/trace/instrumentation/aws/v1/sqs/MessageAttributeInjector.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.amazonaws.services.sqs.model.MessageAttributeValue;
66
import datadog.context.propagation.CarrierSetter;
7+
import datadog.trace.api.Config;
78
import java.util.Map;
89

910
public class MessageAttributeInjector implements CarrierSetter<Map<String, MessageAttributeValue>> {
@@ -13,7 +14,9 @@ public class MessageAttributeInjector implements CarrierSetter<Map<String, Messa
1314
@Override
1415
public void set(
1516
final Map<String, MessageAttributeValue> carrier, final String key, final String value) {
16-
if (carrier.size() < 10 && !carrier.containsKey(DATADOG_KEY)) {
17+
if (carrier.size() < 10
18+
&& !carrier.containsKey(DATADOG_KEY)
19+
&& Config.get().isSqsInjectDatadogAttributeEnabled()) {
1720
String jsonPathway = String.format("{\"%s\": \"%s\"}", key, value);
1821
carrier.put(
1922
DATADOG_KEY,

dd-java-agent/instrumentation/aws-java/aws-java-sqs-1.0/src/main/java/datadog/trace/instrumentation/aws/v1/sqs/SqsInterceptor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import datadog.context.Context;
1919
import datadog.context.propagation.Propagator;
2020
import datadog.context.propagation.Propagators;
21+
import datadog.trace.api.Config;
2122
import datadog.trace.api.datastreams.DataStreamsContext;
2223
import datadog.trace.api.datastreams.DataStreamsTags;
2324
import datadog.trace.bootstrap.ContextStore;
@@ -69,7 +70,8 @@ public AmazonWebServiceRequest beforeMarshalling(AmazonWebServiceRequest request
6970
}
7071
} else if (request instanceof ReceiveMessageRequest) {
7172
ReceiveMessageRequest rmRequest = (ReceiveMessageRequest) request;
72-
if (rmRequest.getMessageAttributeNames().size() < 10
73+
if (Config.get().isSqsInjectDatadogAttributeEnabled()
74+
&& rmRequest.getMessageAttributeNames().size() < 10
7375
&& !rmRequest.getMessageAttributeNames().contains(DATADOG_KEY)) {
7476
List<String> attributeNames = new ArrayList<>(rmRequest.getMessageAttributeNames());
7577
attributeNames.add(DATADOG_KEY);

0 commit comments

Comments
 (0)