-
Notifications
You must be signed in to change notification settings - Fork 342
DSMON-886: add Sqs spring messaging context propagation support #9662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
682dd03
e9813ca
c22ad1f
167a188
930d836
22bd9eb
5293e8c
d9114a8
be69e4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,7 @@ out/ | |
| # Visual Studio Code # | ||
| ###################### | ||
| .vscode | ||
| .cursor | ||
|
|
||
| # Others # | ||
| ########## | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| package datadog.trace.instrumentation.aws.v2.sqs; | ||
|
|
||
| import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; | ||
| import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
| import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
|
||
| import com.google.auto.service.AutoService; | ||
| import datadog.trace.agent.tooling.Instrumenter; | ||
| import datadog.trace.agent.tooling.InstrumenterModule; | ||
| import datadog.trace.bootstrap.ContextStore; | ||
| import datadog.trace.bootstrap.InstrumentationContext; | ||
| import java.util.Map; | ||
| import net.bytebuddy.asm.Advice; | ||
| import net.bytebuddy.description.type.TypeDescription; | ||
| import net.bytebuddy.matcher.ElementMatcher; | ||
| import software.amazon.awssdk.services.sqs.SqsAsyncClient; | ||
| import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; | ||
|
|
||
| /** | ||
| * Instrumentation for SqsAsyncClient receiveMessage calls to track when Spring-managed clients are | ||
| * making receive operations and mark the responses accordingly. | ||
| */ | ||
| @AutoService(InstrumenterModule.class) | ||
| public class SqsAsyncClientInstrumentation extends AbstractSqsInstrumentation | ||
| implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { | ||
|
|
||
| @Override | ||
| public String hierarchyMarkerType() { | ||
| return "software.amazon.awssdk.services.sqs.SqsAsyncClient"; | ||
| } | ||
|
|
||
| @Override | ||
| public ElementMatcher<TypeDescription> hierarchyMatcher() { | ||
| return implementsInterface(named(hierarchyMarkerType())); | ||
| } | ||
|
|
||
| @Override | ||
| public Map<String, String> contextStore() { | ||
| Map<String, String> contextStore = new java.util.HashMap<>(2); | ||
| contextStore.put("software.amazon.awssdk.services.sqs.SqsAsyncClient", "java.lang.Boolean"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe better to use the method |
||
| // Map queue URL to Spring management status | ||
| contextStore.put("java.lang.String", "java.lang.Boolean"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm, this seems suspicious. Do we really need a context store for string types? Perhaps there is a more specific class for this context store.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's not possible to find a more specific class for the context store, then perhaps a value class with a more specific type than Boolean can be used for both queueURL and asyncClient instead? |
||
| return contextStore; | ||
| } | ||
|
|
||
| @Override | ||
| public void methodAdvice(MethodTransformer transformer) { | ||
| // Instrument the receiveMessage method to map queue URLs to Spring management status | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(named("receiveMessage")) | ||
| .and( | ||
| takesArgument( | ||
| 0, named("software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest"))), | ||
| getClass().getName() + "$ReceiveMessageAdvice"); | ||
| } | ||
|
|
||
| public static class ReceiveMessageAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| static void onExit( | ||
| @Advice.This SqsAsyncClient client, @Advice.Argument(0) ReceiveMessageRequest req) { | ||
|
|
||
| Boolean isSpringClient = | ||
| InstrumentationContext.get(SqsAsyncClient.class, Boolean.class).get(client); | ||
|
|
||
| if (Boolean.TRUE.equals(isSpringClient)) { | ||
| // Map the queue URL to Spring management status | ||
| final ContextStore<String, Boolean> queueUrlFlags = | ||
| InstrumentationContext.get(String.class, Boolean.class); | ||
| queueUrlFlags.put(req.queueUrl(), Boolean.TRUE); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| muzzle { | ||
| pass { | ||
| group = 'io.awspring.cloud' | ||
| module = 'spring-cloud-aws-sqs' | ||
| versions = "[3.0.0,)" | ||
| assertInverse = true | ||
| } | ||
| } | ||
|
|
||
| ext { | ||
| minJavaVersionForTests = JavaVersion.VERSION_17 | ||
| } | ||
|
|
||
|
|
||
| apply from: "$rootDir/gradle/java.gradle" | ||
|
|
||
| addTestSuiteForDir('latestDepTest', 'test') | ||
|
|
||
| ["compileTestGroovy", "compileLatestDepTestGroovy"].each { name -> | ||
| tasks.named(name, GroovyCompile) { | ||
| javaLauncher = getJavaLauncherFor(17) | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| compileOnly group: 'software.amazon.awssdk', name: 'sqs', version: '2.20.162' | ||
| compileOnly group: 'org.springframework', name: 'spring-messaging', version: '5.3.23' | ||
|
|
||
| testImplementation project(':dd-java-agent:instrumentation:trace-annotation') | ||
| testImplementation project(':dd-java-agent:instrumentation:aws-java:aws-java-sdk-2.2') | ||
| testImplementation project(':dd-java-agent:instrumentation:aws-java:aws-java-sqs-2.0') | ||
| testImplementation project(':dd-java-agent:instrumentation:spring:spring-messaging-4.0') | ||
|
|
||
| testImplementation group: 'org.springframework', name: 'spring-context', version: '6.1.10' | ||
| testImplementation group: 'org.springframework', name: 'spring-test', version: '6.1.10' | ||
| testImplementation group: 'org.springframework', name: 'spring-core', version: '6.1.10' | ||
| testImplementation group: 'io.awspring.cloud', name: 'spring-cloud-aws-sqs', version: '3.1.0' | ||
| testImplementation group: 'software.amazon.awssdk', name: 'sqs', version: '2.20.162' | ||
| testImplementation group: 'software.amazon.awssdk', name: 'aws-core', version: '2.20.162' | ||
| testImplementation group: 'org.testcontainers', name: 'localstack', version: libs.versions.testcontainers.get() | ||
| testImplementation 'org.slf4j:slf4j-api:2.0.13' | ||
| testImplementation 'ch.qos.logback:logback-classic:1.4.14' | ||
| testImplementation 'ch.qos.logback:logback-core:1.4.14' | ||
|
|
||
| latestDepTestImplementation group: 'org.springframework', name: 'spring-context', version: '6.+' | ||
| latestDepTestImplementation group: 'org.springframework', name: 'spring-test', version: '6.+' | ||
| latestDepTestImplementation group: 'org.springframework', name: 'spring-core', version: '6.+' | ||
| latestDepTestImplementation group: 'software.amazon.awssdk', name: 'sqs', version: '2.+' | ||
| latestDepTestImplementation group: 'software.amazon.awssdk', name: 'aws-core', version: '2.+' | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the only implementation is the DefaultSqsAsyncClient. That should be declared in knownMatchingTypes.