Merge pull request #1158 from DataDog/tyler/aws-1-tagging
Add various tags for AWS SDK v1.x
This commit is contained in:
commit
03dd908fdb
|
@ -39,9 +39,16 @@ dependencies {
|
|||
|
||||
// Include httpclient instrumentation for testing because it is a dependency for aws-sdk.
|
||||
testCompile project(':dd-java-agent:instrumentation:apache-httpclient-4')
|
||||
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.106'
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-rds', version: '1.11.106'
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-ec2', version: '1.11.106'
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-kinesis', version: '1.11.106'
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-sqs', version: '1.11.106'
|
||||
testCompile group: 'com.amazonaws', name: 'aws-java-sdk-dynamodb', version: '1.11.106'
|
||||
|
||||
// needed for kinesis:
|
||||
testCompile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-cbor', version: versions.jackson
|
||||
|
||||
test_before_1_11_106Compile(group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.0') {
|
||||
force = true
|
||||
|
@ -52,10 +59,22 @@ dependencies {
|
|||
test_before_1_11_106Compile(group: 'com.amazonaws', name: 'aws-java-sdk-ec2', version: '1.11.0') {
|
||||
force = true
|
||||
}
|
||||
test_before_1_11_106Compile(group: 'com.amazonaws', name: 'aws-java-sdk-kinesis', version: '1.11.0') {
|
||||
force = true
|
||||
}
|
||||
test_before_1_11_106Compile(group: 'com.amazonaws', name: 'aws-java-sdk-sqs', version: '1.11.0') {
|
||||
force = true
|
||||
}
|
||||
test_before_1_11_106Compile(group: 'com.amazonaws', name: 'aws-java-sdk-dynamodb', version: '1.11.0') {
|
||||
force = true
|
||||
}
|
||||
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '+'
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-rds', version: '+'
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-ec2', version: '+'
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-kinesis', version: '+'
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-sqs', version: '+'
|
||||
latestDepTestCompile group: 'com.amazonaws', name: 'aws-java-sdk-dynamodb', version: '+'
|
||||
}
|
||||
|
||||
test.dependsOn test_before_1_11_106
|
||||
|
|
|
@ -5,9 +5,11 @@ import static net.bytebuddy.matcher.ElementMatchers.declaresField;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceRequest;
|
||||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.InstrumentationContext;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
@ -39,6 +41,7 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
|
|||
"datadog.trace.agent.decorator.ClientDecorator",
|
||||
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||
packageName + ".AwsSdkClientDecorator",
|
||||
packageName + ".RequestMeta",
|
||||
packageName + ".TracingRequestHandler",
|
||||
};
|
||||
}
|
||||
|
@ -49,6 +52,11 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
|
|||
isConstructor(), AWSClientInstrumentation.class.getName() + "$AWSClientAdvice");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> contextStore() {
|
||||
return singletonMap("com.amazonaws.AmazonWebServiceRequest", packageName + ".RequestMeta");
|
||||
}
|
||||
|
||||
public static class AWSClientAdvice {
|
||||
// Since we're instrumenting the constructor, we can't add onThrowable.
|
||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||
|
@ -62,7 +70,9 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
}
|
||||
if (!hasDDHandler) {
|
||||
handlers.add(TracingRequestHandler.INSTANCE);
|
||||
handlers.add(
|
||||
new TracingRequestHandler(
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import static datadog.trace.instrumentation.aws.v0.AwsSdkClientDecorator.DECORATE;
|
||||
import static datadog.trace.instrumentation.aws.v0.OnErrorDecorator.DECORATE;
|
||||
import static datadog.trace.instrumentation.aws.v0.RequestMeta.SCOPE_CONTEXT_KEY;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
|
@ -40,10 +41,8 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
|
|||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.agent.decorator.BaseDecorator",
|
||||
"datadog.trace.agent.decorator.ClientDecorator",
|
||||
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||
packageName + ".AwsSdkClientDecorator",
|
||||
packageName + ".TracingRequestHandler",
|
||||
packageName + ".OnErrorDecorator",
|
||||
packageName + ".RequestMeta",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -60,9 +59,9 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Argument(value = 0, optional = true) final Request<?> request,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
if (throwable != null) {
|
||||
final AgentScope scope = request.getHandlerContext(TracingRequestHandler.SCOPE_CONTEXT_KEY);
|
||||
final AgentScope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
if (scope != null) {
|
||||
request.addHandlerContext(TracingRequestHandler.SCOPE_CONTEXT_KEY, null);
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, null);
|
||||
DECORATE.onError(scope.span(), throwable);
|
||||
DECORATE.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
|
@ -96,10 +95,9 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
|
|||
@Advice.FieldValue("request") final Request<?> request,
|
||||
@Advice.Thrown final Throwable throwable) {
|
||||
if (throwable != null) {
|
||||
final AgentScope scope =
|
||||
request.getHandlerContext(TracingRequestHandler.SCOPE_CONTEXT_KEY);
|
||||
final AgentScope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
if (scope != null) {
|
||||
request.addHandlerContext(TracingRequestHandler.SCOPE_CONTEXT_KEY, null);
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, null);
|
||||
DECORATE.onError(scope.span(), throwable);
|
||||
DECORATE.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceRequest;
|
||||
import com.amazonaws.AmazonWebServiceResponse;
|
||||
import com.amazonaws.Request;
|
||||
import com.amazonaws.Response;
|
||||
import datadog.trace.agent.decorator.HttpClientDecorator;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.bootstrap.ContextStore;
|
||||
import datadog.trace.instrumentation.api.AgentSpan;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -12,12 +14,17 @@ import java.util.Map;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AwsSdkClientDecorator extends HttpClientDecorator<Request, Response> {
|
||||
public static final AwsSdkClientDecorator DECORATE = new AwsSdkClientDecorator();
|
||||
|
||||
static final String COMPONENT_NAME = "java-aws-sdk";
|
||||
|
||||
private final Map<String, String> serviceNames = new ConcurrentHashMap<>();
|
||||
private final Map<Class, String> operationNames = new ConcurrentHashMap<>();
|
||||
private final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore;
|
||||
|
||||
public AwsSdkClientDecorator(
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore) {
|
||||
this.contextStore = contextStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentSpan onRequest(final AgentSpan span, final Request request) {
|
||||
|
@ -25,7 +32,8 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<Request, Response
|
|||
super.onRequest(span, request);
|
||||
|
||||
final String awsServiceName = request.getServiceName();
|
||||
final Class<?> awsOperation = request.getOriginalRequest().getClass();
|
||||
final AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
|
||||
final Class<?> awsOperation = originalRequest.getClass();
|
||||
|
||||
span.setTag("aws.agent", COMPONENT_NAME);
|
||||
span.setTag("aws.service", awsServiceName);
|
||||
|
@ -36,6 +44,17 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<Request, Response
|
|||
DDTags.RESOURCE_NAME,
|
||||
remapServiceName(awsServiceName) + "." + remapOperationName(awsOperation));
|
||||
|
||||
if (contextStore != null) {
|
||||
final RequestMeta requestMeta = contextStore.get(originalRequest);
|
||||
if (requestMeta != null) {
|
||||
span.setTag("aws.bucket.name", requestMeta.getBucketName());
|
||||
span.setTag("aws.queue.url", requestMeta.getQueueUrl());
|
||||
span.setTag("aws.queue.name", requestMeta.getQueueName());
|
||||
span.setTag("aws.stream.name", requestMeta.getStreamName());
|
||||
span.setTag("aws.table.name", requestMeta.getTableName());
|
||||
}
|
||||
}
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import datadog.trace.agent.decorator.BaseDecorator;
|
||||
|
||||
public class OnErrorDecorator extends BaseDecorator {
|
||||
public static final OnErrorDecorator DECORATE = new OnErrorDecorator();
|
||||
|
||||
@Override
|
||||
protected String[] instrumentationNames() {
|
||||
return new String[] {"aws-sdk"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String spanType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String component() {
|
||||
return "java-aws-sdk";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceRequest;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.ContextStore;
|
||||
import datadog.trace.bootstrap.InstrumentationContext;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class RequestInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public RequestInstrumentation() {
|
||||
super("aws-sdk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||
return safeHasSuperType(named("com.amazonaws.AmazonWebServiceRequest"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
packageName + ".RequestMeta",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||
final Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("setBucketName").and(takesArgument(0, String.class)),
|
||||
RequestInstrumentation.class.getName() + "$BucketNameAdvice");
|
||||
transformers.put(
|
||||
named("setQueueUrl").and(takesArgument(0, String.class)),
|
||||
RequestInstrumentation.class.getName() + "$QueueUrlAdvice");
|
||||
transformers.put(
|
||||
named("setQueueName").and(takesArgument(0, String.class)),
|
||||
RequestInstrumentation.class.getName() + "$QueueNameAdvice");
|
||||
transformers.put(
|
||||
named("setStreamName").and(takesArgument(0, String.class)),
|
||||
RequestInstrumentation.class.getName() + "$StreamNameAdvice");
|
||||
transformers.put(
|
||||
named("setTableName").and(takesArgument(0, String.class)),
|
||||
RequestInstrumentation.class.getName() + "$TableNameAdvice");
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> contextStore() {
|
||||
return singletonMap("com.amazonaws.AmazonWebServiceRequest", packageName + ".RequestMeta");
|
||||
}
|
||||
|
||||
public static class BucketNameAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void methodEnter(
|
||||
@Advice.Argument(0) final String value,
|
||||
@Advice.This final AmazonWebServiceRequest request) {
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore =
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class);
|
||||
RequestMeta requestMeta = contextStore.get(request);
|
||||
if (requestMeta == null) {
|
||||
requestMeta = new RequestMeta();
|
||||
contextStore.put(request, requestMeta);
|
||||
}
|
||||
requestMeta.setBucketName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueueUrlAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void methodEnter(
|
||||
@Advice.Argument(0) final String value,
|
||||
@Advice.This final AmazonWebServiceRequest request) {
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore =
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class);
|
||||
RequestMeta requestMeta = contextStore.get(request);
|
||||
if (requestMeta == null) {
|
||||
requestMeta = new RequestMeta();
|
||||
contextStore.put(request, requestMeta);
|
||||
}
|
||||
requestMeta.setQueueUrl(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueueNameAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void methodEnter(
|
||||
@Advice.Argument(0) final String value,
|
||||
@Advice.This final AmazonWebServiceRequest request) {
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore =
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class);
|
||||
RequestMeta requestMeta = contextStore.get(request);
|
||||
if (requestMeta == null) {
|
||||
requestMeta = new RequestMeta();
|
||||
contextStore.put(request, requestMeta);
|
||||
}
|
||||
requestMeta.setQueueName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StreamNameAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void methodEnter(
|
||||
@Advice.Argument(0) final String value,
|
||||
@Advice.This final AmazonWebServiceRequest request) {
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore =
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class);
|
||||
RequestMeta requestMeta = contextStore.get(request);
|
||||
if (requestMeta == null) {
|
||||
requestMeta = new RequestMeta();
|
||||
contextStore.put(request, requestMeta);
|
||||
}
|
||||
requestMeta.setStreamName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TableNameAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void methodEnter(
|
||||
@Advice.Argument(0) final String value,
|
||||
@Advice.This final AmazonWebServiceRequest request) {
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore =
|
||||
InstrumentationContext.get(AmazonWebServiceRequest.class, RequestMeta.class);
|
||||
RequestMeta requestMeta = contextStore.get(request);
|
||||
if (requestMeta == null) {
|
||||
requestMeta = new RequestMeta();
|
||||
contextStore.put(request, requestMeta);
|
||||
}
|
||||
requestMeta.setTableName(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import com.amazonaws.handlers.HandlerContextKey;
|
||||
import datadog.trace.instrumentation.api.AgentScope;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RequestMeta {
|
||||
// Note: aws1.x sdk doesn't have any truly async clients so we can store scope in request context
|
||||
// safely.
|
||||
public static final HandlerContextKey<AgentScope> SCOPE_CONTEXT_KEY =
|
||||
new HandlerContextKey<>("DatadogScope");
|
||||
|
||||
private String bucketName;
|
||||
private String queueUrl;
|
||||
private String queueName;
|
||||
private String streamName;
|
||||
private String tableName;
|
||||
}
|
|
@ -2,24 +2,25 @@ package datadog.trace.instrumentation.aws.v0;
|
|||
|
||||
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
|
||||
import static datadog.trace.instrumentation.api.AgentTracer.startSpan;
|
||||
import static datadog.trace.instrumentation.aws.v0.AwsSdkClientDecorator.DECORATE;
|
||||
import static datadog.trace.instrumentation.aws.v0.RequestMeta.SCOPE_CONTEXT_KEY;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceRequest;
|
||||
import com.amazonaws.Request;
|
||||
import com.amazonaws.Response;
|
||||
import com.amazonaws.handlers.HandlerContextKey;
|
||||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import datadog.trace.bootstrap.ContextStore;
|
||||
import datadog.trace.instrumentation.api.AgentScope;
|
||||
import datadog.trace.instrumentation.api.AgentSpan;
|
||||
|
||||
/** Tracing Request Handler */
|
||||
public class TracingRequestHandler extends RequestHandler2 {
|
||||
public static TracingRequestHandler INSTANCE = new TracingRequestHandler();
|
||||
|
||||
// Note: aws1.x sdk doesn't have any truly async clients so we can store scope in request context
|
||||
// safely.
|
||||
public static final HandlerContextKey<AgentScope> SCOPE_CONTEXT_KEY =
|
||||
new HandlerContextKey<>("DatadogScope");
|
||||
private final AwsSdkClientDecorator decorate;
|
||||
|
||||
public TracingRequestHandler(
|
||||
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore) {
|
||||
decorate = new AwsSdkClientDecorator(contextStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmazonWebServiceRequest beforeMarshalling(final AmazonWebServiceRequest request) {
|
||||
|
@ -29,8 +30,8 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
@Override
|
||||
public void beforeRequest(final Request<?> request) {
|
||||
final AgentSpan span = startSpan("aws.command");
|
||||
DECORATE.afterStart(span);
|
||||
DECORATE.onRequest(span, request);
|
||||
decorate.afterStart(span);
|
||||
decorate.onRequest(span, request);
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, activateSpan(span, true));
|
||||
}
|
||||
|
||||
|
@ -39,8 +40,8 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
final AgentScope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
if (scope != null) {
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, null);
|
||||
DECORATE.onResponse(scope.span(), response);
|
||||
DECORATE.beforeFinish(scope.span());
|
||||
decorate.onResponse(scope.span(), response);
|
||||
decorate.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
|
@ -50,8 +51,8 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
final AgentScope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
if (scope != null) {
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, null);
|
||||
DECORATE.onError(scope.span(), e);
|
||||
DECORATE.beforeFinish(scope.span());
|
||||
decorate.onError(scope.span(), e);
|
||||
decorate.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,18 @@ import com.amazonaws.client.builder.AwsClientBuilder
|
|||
import com.amazonaws.handlers.RequestHandler2
|
||||
import com.amazonaws.regions.Regions
|
||||
import com.amazonaws.retry.PredefinedRetryPolicies
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder
|
||||
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest
|
||||
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder
|
||||
import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder
|
||||
import com.amazonaws.services.kinesis.model.DeleteStreamRequest
|
||||
import com.amazonaws.services.rds.AmazonRDSClientBuilder
|
||||
import com.amazonaws.services.rds.model.DeleteOptionGroupRequest
|
||||
import com.amazonaws.services.s3.AmazonS3Client
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder
|
||||
import com.amazonaws.services.sqs.AmazonSQSClientBuilder
|
||||
import com.amazonaws.services.sqs.model.CreateQueueRequest
|
||||
import com.amazonaws.services.sqs.model.SendMessageRequest
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.api.DDSpanTypes
|
||||
import datadog.trace.instrumentation.api.Tags
|
||||
|
@ -143,12 +150,15 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "$server.address"
|
||||
"aws.operation" "${operation}Request"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
for (def addedTag : additionalTags) {
|
||||
"$addedTag.key" "$addedTag.value"
|
||||
}
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
operationName "http.request"
|
||||
resourceName "$method /$url"
|
||||
resourceName "$method $path"
|
||||
spanType DDSpanTypes.HTTP_CLIENT
|
||||
errored false
|
||||
childOf(span(0))
|
||||
|
@ -157,7 +167,7 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT
|
||||
"$Tags.PEER_HOSTNAME" "localhost"
|
||||
"$Tags.PEER_PORT" server.address.port
|
||||
"$Tags.HTTP_URL" "$server.address/$url"
|
||||
"$Tags.HTTP_URL" "${server.address}${path}"
|
||||
"$Tags.HTTP_METHOD" "$method"
|
||||
"$Tags.HTTP_STATUS" 200
|
||||
defaultTags()
|
||||
|
@ -169,23 +179,41 @@ class AWSClientTest extends AgentTestRunner {
|
|||
server.lastRequest.headers.get("x-datadog-parent-id") == null
|
||||
|
||||
where:
|
||||
service | operation | method | url | handlerCount | call | body | client
|
||||
"S3" | "CreateBucket" | "PUT" | "testbucket/" | 1 | { client -> client.createBucket("testbucket") } | "" | AmazonS3ClientBuilder.standard().withPathStyleAccessEnabled(true).withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build()
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | 1 | { client -> client.getObject("someBucket", "someKey") } | "" | AmazonS3ClientBuilder.standard().withPathStyleAccessEnabled(true).withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build()
|
||||
"EC2" | "AllocateAddress" | "POST" | "" | 4 | { client -> client.allocateAddress() } | """
|
||||
<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||
<publicIp>192.0.2.1</publicIp>
|
||||
<domain>standard</domain>
|
||||
</AllocateAddressResponse>
|
||||
""" | AmazonEC2ClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build()
|
||||
"RDS" | "DeleteOptionGroup" | "POST" | "" | 5 | { client -> client.deleteOptionGroup(new DeleteOptionGroupRequest()) } | """
|
||||
service | operation | method | path | handlerCount | client | call | additionalTags | body
|
||||
"S3" | "CreateBucket" | "PUT" | "/testbucket/" | 1 | AmazonS3ClientBuilder.standard().withPathStyleAccessEnabled(true).withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { client -> client.createBucket("testbucket") } | ["aws.bucket.name": "testbucket"] | ""
|
||||
"S3" | "GetObject" | "GET" | "/someBucket/someKey" | 1 | AmazonS3ClientBuilder.standard().withPathStyleAccessEnabled(true).withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { client -> client.getObject("someBucket", "someKey") } | ["aws.bucket.name": "someBucket"] | ""
|
||||
"DynamoDBv2" | "CreateTable" | "POST" | "/" | 1 | AmazonDynamoDBClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { c -> c.createTable(new CreateTableRequest("sometable", null)) } | ["aws.table.name": "sometable"] | ""
|
||||
"Kinesis" | "DeleteStream" | "POST" | "/" | 1 | AmazonKinesisClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { c -> c.deleteStream(new DeleteStreamRequest().withStreamName("somestream")) } | ["aws.stream.name": "somestream"] | ""
|
||||
"SQS" | "CreateQueue" | "POST" | "/" | 4 | AmazonSQSClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { c -> c.createQueue(new CreateQueueRequest("somequeue")) } | ["aws.queue.name": "somequeue"] | """
|
||||
<CreateQueueResponse>
|
||||
<CreateQueueResult><QueueUrl>https://queue.amazonaws.com/123456789012/MyQueue</QueueUrl></CreateQueueResult>
|
||||
<ResponseMetadata><RequestId>7a62c49f-347e-4fc4-9331-6e8e7a96aa73</RequestId></ResponseMetadata>
|
||||
</CreateQueueResponse>
|
||||
"""
|
||||
"SQS" | "SendMessage" | "POST" | "/someurl" | 4 | AmazonSQSClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { c -> c.sendMessage(new SendMessageRequest("someurl", "")) } | ["aws.queue.url": "someurl"] | """
|
||||
<SendMessageResponse>
|
||||
<SendMessageResult>
|
||||
<MD5OfMessageBody>d41d8cd98f00b204e9800998ecf8427e</MD5OfMessageBody>
|
||||
<MD5OfMessageAttributes>3ae8f24a165a8cedc005670c81a27295</MD5OfMessageAttributes>
|
||||
<MessageId>5fea7756-0ea4-451a-a703-a558b933e274</MessageId>
|
||||
</SendMessageResult>
|
||||
<ResponseMetadata><RequestId>27daac76-34dd-47df-bd01-1f6e873584a0</RequestId></ResponseMetadata>
|
||||
</SendMessageResponse>
|
||||
"""
|
||||
"EC2" | "AllocateAddress" | "POST" | "/" | 4 | AmazonEC2ClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { client -> client.allocateAddress() } | [:] | """
|
||||
<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||
<publicIp>192.0.2.1</publicIp>
|
||||
<domain>standard</domain>
|
||||
</AllocateAddressResponse>
|
||||
"""
|
||||
"RDS" | "DeleteOptionGroup" | "POST" | "/" | 5 | AmazonRDSClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build() | { client -> client.deleteOptionGroup(new DeleteOptionGroupRequest()) } | [:] | """
|
||||
<DeleteOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||
<ResponseMetadata>
|
||||
<RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DeleteOptionGroupResponse>
|
||||
""" | AmazonRDSClientBuilder.standard().withEndpointConfiguration(endpoint).withCredentials(credentialsProvider).build()
|
||||
"""
|
||||
}
|
||||
|
||||
def "send #operation request to closed port"() {
|
||||
|
@ -216,6 +244,9 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "http://localhost:${UNUSABLE_PORT}"
|
||||
"aws.operation" "${operation}Request"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
for (def addedTag : additionalTags) {
|
||||
"$addedTag.key" "$addedTag.value"
|
||||
}
|
||||
errorTags SdkClientException, ~/Unable to execute HTTP request/
|
||||
defaultTags()
|
||||
}
|
||||
|
@ -241,8 +272,8 @@ class AWSClientTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
service | operation | method | url | call | body | client
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | { client -> client.getObject("someBucket", "someKey") } | "" | new AmazonS3Client(CREDENTIALS_PROVIDER_CHAIN, new ClientConfiguration().withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(0))).withEndpoint("http://localhost:${UNUSABLE_PORT}")
|
||||
service | operation | method | url | call | additionalTags | body | client
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | { client -> client.getObject("someBucket", "someKey") } | ["aws.bucket.name": "someBucket"] | "" | new AmazonS3Client(CREDENTIALS_PROVIDER_CHAIN, new ClientConfiguration().withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(0))).withEndpoint("http://localhost:${UNUSABLE_PORT}")
|
||||
}
|
||||
|
||||
def "naughty request handler doesn't break the trace"() {
|
||||
|
@ -325,6 +356,7 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "$server.address"
|
||||
"aws.operation" "GetObjectRequest"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
"aws.bucket.name" "someBucket"
|
||||
try {
|
||||
errorTags AmazonClientException, ~/Unable to execute HTTP request/
|
||||
} catch (AssertionError e) {
|
||||
|
|
|
@ -113,12 +113,15 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "$server.address"
|
||||
"aws.operation" "${operation}Request"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
for (def addedTag : additionalTags) {
|
||||
"$addedTag.key" "$addedTag.value"
|
||||
}
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
operationName "http.request"
|
||||
resourceName "$method /$url"
|
||||
resourceName "$method $path"
|
||||
spanType DDSpanTypes.HTTP_CLIENT
|
||||
errored false
|
||||
childOf(span(0))
|
||||
|
@ -127,7 +130,7 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT
|
||||
"$Tags.PEER_HOSTNAME" "localhost"
|
||||
"$Tags.PEER_PORT" server.address.port
|
||||
"$Tags.HTTP_URL" "$server.address/$url"
|
||||
"$Tags.HTTP_URL" "${server.address}${path}"
|
||||
"$Tags.HTTP_METHOD" "$method"
|
||||
"$Tags.HTTP_STATUS" 200
|
||||
defaultTags()
|
||||
|
@ -139,23 +142,23 @@ class AWSClientTest extends AgentTestRunner {
|
|||
server.lastRequest.headers.get("x-datadog-parent-id") == null
|
||||
|
||||
where:
|
||||
service | operation | method | url | handlerCount | call | body | client
|
||||
"S3" | "CreateBucket" | "PUT" | "testbucket/" | 1 | { client -> client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build()); client.createBucket("testbucket") } | "" | new AmazonS3Client().withEndpoint("http://localhost:$server.address.port")
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | 1 | { client -> client.getObject("someBucket", "someKey") } | "" | new AmazonS3Client().withEndpoint("http://localhost:$server.address.port")
|
||||
"EC2" | "AllocateAddress" | "POST" | "" | 4 | { client -> client.allocateAddress() } | """
|
||||
service | operation | method | path | handlerCount | client | additionalTags | call | body
|
||||
"S3" | "CreateBucket" | "PUT" | "/testbucket/" | 1 | new AmazonS3Client().withEndpoint("http://localhost:$server.address.port") | ["aws.bucket.name": "testbucket"] | { client -> client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build()); client.createBucket("testbucket") } | ""
|
||||
"S3" | "GetObject" | "GET" | "/someBucket/someKey" | 1 | new AmazonS3Client().withEndpoint("http://localhost:$server.address.port") | ["aws.bucket.name": "someBucket"] | { client -> client.getObject("someBucket", "someKey") } | ""
|
||||
"EC2" | "AllocateAddress" | "POST" | "/" | 4 | new AmazonEC2Client().withEndpoint("http://localhost:$server.address.port") | [:] | { client -> client.allocateAddress() } | """
|
||||
<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
|
||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||
<publicIp>192.0.2.1</publicIp>
|
||||
<domain>standard</domain>
|
||||
</AllocateAddressResponse>
|
||||
""" | new AmazonEC2Client().withEndpoint("http://localhost:$server.address.port")
|
||||
"RDS" | "DeleteOptionGroup" | "POST" | "" | 1 | { client -> client.deleteOptionGroup(new DeleteOptionGroupRequest()) } | """
|
||||
"""
|
||||
"RDS" | "DeleteOptionGroup" | "POST" | "/" | 1 | new AmazonRDSClient().withEndpoint("http://localhost:$server.address.port") | [:] | { client -> client.deleteOptionGroup(new DeleteOptionGroupRequest()) } | """
|
||||
<DeleteOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
|
||||
<ResponseMetadata>
|
||||
<RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DeleteOptionGroupResponse>
|
||||
""" | new AmazonRDSClient().withEndpoint("http://localhost:$server.address.port")
|
||||
"""
|
||||
}
|
||||
|
||||
def "send #operation request to closed port"() {
|
||||
|
@ -186,6 +189,9 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "http://localhost:${UNUSABLE_PORT}"
|
||||
"aws.operation" "${operation}Request"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
for (def addedTag : additionalTags) {
|
||||
"$addedTag.key" "$addedTag.value"
|
||||
}
|
||||
errorTags AmazonClientException, ~/Unable to execute HTTP request/
|
||||
defaultTags()
|
||||
}
|
||||
|
@ -211,8 +217,8 @@ class AWSClientTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
service | operation | method | url | call | body | client
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | { client -> client.getObject("someBucket", "someKey") } | "" | new AmazonS3Client(CREDENTIALS_PROVIDER_CHAIN, new ClientConfiguration().withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(0))).withEndpoint("http://localhost:${UNUSABLE_PORT}")
|
||||
service | operation | method | url | call | additionalTags | body | client
|
||||
"S3" | "GetObject" | "GET" | "someBucket/someKey" | { client -> client.getObject("someBucket", "someKey") } | ["aws.bucket.name": "someBucket"] | "" | new AmazonS3Client(CREDENTIALS_PROVIDER_CHAIN, new ClientConfiguration().withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(0))).withEndpoint("http://localhost:${UNUSABLE_PORT}")
|
||||
}
|
||||
|
||||
def "naughty request handler doesn't break the trace"() {
|
||||
|
@ -249,6 +255,7 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "https://s3.amazonaws.com"
|
||||
"aws.operation" "GetObjectRequest"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
"aws.bucket.name" "someBucket"
|
||||
errorTags RuntimeException, "bad handler"
|
||||
defaultTags()
|
||||
}
|
||||
|
@ -295,6 +302,7 @@ class AWSClientTest extends AgentTestRunner {
|
|||
"aws.endpoint" "http://localhost:$server.address.port"
|
||||
"aws.operation" "GetObjectRequest"
|
||||
"aws.agent" "java-aws-sdk"
|
||||
"aws.bucket.name" "someBucket"
|
||||
errorTags AmazonClientException, ~/Unable to execute HTTP request/
|
||||
defaultTags()
|
||||
}
|
||||
|
|
|
@ -22,21 +22,21 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<SdkHttpRequest, S
|
|||
request
|
||||
.getValueForField("Bucket", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.bucket.name", name));
|
||||
// DynamoDB
|
||||
request
|
||||
.getValueForField("TableName", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.table.name", name));
|
||||
// SQS
|
||||
request
|
||||
.getValueForField("QueueName", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.queue.name", name));
|
||||
request
|
||||
.getValueForField("QueueUrl", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.queue.url", name));
|
||||
request
|
||||
.getValueForField("QueueName", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.queue.name", name));
|
||||
// Kinesis
|
||||
request
|
||||
.getValueForField("StreamName", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.stream.name", name));
|
||||
// DynamoDB
|
||||
request
|
||||
.getValueForField("TableName", String.class)
|
||||
.ifPresent(name -> span.setTag("aws.table.name", name));
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue