Skip to content

Commit 0ed8bfe

Browse files
committed
Create S3 instrumentation
1 parent 5b58772 commit 0ed8bfe

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
muzzle {
2+
pass {
3+
group = "software.amazon.awssdk"
4+
module = "s3"
5+
versions = "[2.0,3)"
6+
assertInverse = true
7+
}
8+
}
9+
10+
apply from: "$rootDir/gradle/java.gradle"
11+
12+
addTestSuiteForDir('latestDepTest', 'test')
13+
addTestSuiteExtendingForDir('latestDepForkedTest', 'latestDepTest', 'test')
14+
15+
dependencies {
16+
compileOnly group: 'software.amazon.awssdk', name: 's3', version: '2.29.26'
17+
18+
// Include httpclient instrumentation for testing because it is a dependency for aws-sdk.
19+
testImplementation project(':dd-java-agent:instrumentation:apache-httpclient-4')
20+
testImplementation project(':dd-java-agent:instrumentation:aws-java-sdk-2.2')
21+
testImplementation 'software.amazon.awssdk:s3:2.29.26'
22+
testImplementation 'org.testcontainers:localstack:1.20.1'
23+
24+
latestDepTestImplementation group: 'software.amazon.awssdk', name: 's3', version: '+'
25+
}
26+
27+
tasks.withType(Test).configureEach {
28+
usesService(testcontainersLimit)
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package datadog.trace.instrumentation.aws.v2.s3;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
5+
6+
import com.google.auto.service.AutoService;
7+
import datadog.trace.agent.tooling.Instrumenter;
8+
import datadog.trace.agent.tooling.InstrumenterModule;
9+
import java.util.List;
10+
import net.bytebuddy.asm.Advice;
11+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
12+
13+
@AutoService(InstrumenterModule.class)
14+
public final class S3ClientInstrumentation extends InstrumenterModule.Tracing
15+
implements Instrumenter.ForSingleType {
16+
public S3ClientInstrumentation() {
17+
super("s3");
18+
}
19+
20+
@Override
21+
public String instrumentedType() {
22+
return "software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder";
23+
}
24+
25+
@Override
26+
public void methodAdvice(MethodTransformer transformer) {
27+
transformer.applyAdvice(
28+
isMethod().and(named("resolveExecutionInterceptors")),
29+
S3ClientInstrumentation.class.getName() + "$AwsS3BuilderAdvice");
30+
}
31+
32+
@Override
33+
public String[] helperClassNames() {
34+
return new String[] {packageName + ".S3Interceptor", packageName + ".TextMapInjectAdapter"};
35+
}
36+
37+
public static class AwsS3BuilderAdvice {
38+
@Advice.OnMethodExit(suppress = Throwable.class)
39+
public static void addHandler(@Advice.Return final List<ExecutionInterceptor> interceptors) {
40+
for (ExecutionInterceptor interceptor : interceptors) {
41+
if (interceptor instanceof S3Interceptor) {
42+
return; // list already has our interceptor, return to builder
43+
}
44+
}
45+
interceptors.add(new S3Interceptor());
46+
}
47+
}
48+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package datadog.trace.instrumentation.aws.v2.s3;
2+
3+
import software.amazon.awssdk.core.SdkRequest;
4+
import software.amazon.awssdk.core.interceptor.Context;
5+
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
6+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
7+
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest;
8+
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
9+
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
10+
11+
public class S3Interceptor implements ExecutionInterceptor {
12+
@Override
13+
public SdkRequest modifyRequest(
14+
Context.ModifyRequest context, ExecutionAttributes executionAttributes) {
15+
if (context.request() instanceof PutObjectRequest) {
16+
System.out.println("[DEBUG] PutObjectRequest");
17+
} else if (context.request() instanceof CopyObjectRequest) {
18+
System.out.println("[DEBUG] CopyObjectRequest");
19+
} else if (context.request() instanceof CompleteMultipartUploadRequest) {
20+
System.out.println("[DEBUG] CompleteMultipartUploadRequest");
21+
} else {
22+
System.out.println("[DEBUG] unknown request");
23+
}
24+
25+
return context.request();
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package datadog.trace.instrumentation.aws.v2.s3;
2+
3+
import datadog.trace.bootstrap.instrumentation.api.AgentPropagation;
4+
5+
public class TextMapInjectAdapter implements AgentPropagation.Setter<StringBuilder> {
6+
7+
public static final TextMapInjectAdapter SETTER = new TextMapInjectAdapter();
8+
9+
@Override
10+
public void set(final StringBuilder builder, final String key, final String value) {
11+
builder.append('"').append(key).append("\":\"").append(value).append("\",");
12+
}
13+
}

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ include ':dd-java-agent:instrumentation:aws-java-sns-1.0'
196196
include ':dd-java-agent:instrumentation:aws-java-sns-2.0'
197197
include ':dd-java-agent:instrumentation:aws-java-sqs-1.0'
198198
include ':dd-java-agent:instrumentation:aws-java-sqs-2.0'
199+
include ':dd-java-agent:instrumentation:aws-java-s3-2.0'
199200
include ':dd-java-agent:instrumentation:aws-lambda-handler'
200201
include ':dd-java-agent:instrumentation:axis-2'
201202
include ':dd-java-agent:instrumentation:axway-api'

0 commit comments

Comments
 (0)