Merge pull request #723 from DataDog/tyler/aws-decorators
Migrate AWS SDK instrumentation to decorators
This commit is contained in:
commit
8f9ea87ef6
|
@ -8,7 +8,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
|
@ -36,8 +35,11 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.aws.v0.TracingRequestHandler",
|
||||
"datadog.trace.instrumentation.aws.v0.SpanDecorator"
|
||||
"datadog.trace.agent.decorator.BaseDecorator",
|
||||
"datadog.trace.agent.decorator.ClientDecorator",
|
||||
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||
packageName + ".AwsSdkClientDecorator",
|
||||
packageName + ".TracingRequestHandler",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
}
|
||||
if (!hasDDHandler) {
|
||||
handlers.add(new TracingRequestHandler(GlobalTracer.get()));
|
||||
handlers.add(TracingRequestHandler.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceResponse;
|
||||
import com.amazonaws.Request;
|
||||
import com.amazonaws.Response;
|
||||
import datadog.trace.agent.decorator.HttpClientDecorator;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Span;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
class AwsSdkClientDecorator extends HttpClientDecorator<Request, Response> {
|
||||
public static final AwsSdkClientDecorator INSTANCE = 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<>();
|
||||
|
||||
@Override
|
||||
public Span onRequest(final Span span, final Request request) {
|
||||
// Call super first because we override the resource name below.
|
||||
super.onRequest(span, request);
|
||||
|
||||
final String awsServiceName = request.getServiceName();
|
||||
final Class<?> awsOperation = request.getOriginalRequest().getClass();
|
||||
|
||||
span.setTag("aws.agent", COMPONENT_NAME);
|
||||
span.setTag("aws.service", awsServiceName);
|
||||
span.setTag("aws.operation", awsOperation.getSimpleName());
|
||||
span.setTag("aws.endpoint", request.getEndpoint().toString());
|
||||
|
||||
span.setTag(
|
||||
DDTags.RESOURCE_NAME,
|
||||
remapServiceName(awsServiceName) + "." + remapOperationName(awsOperation));
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span onResponse(final Span span, final Response response) {
|
||||
if (response.getAwsResponse() instanceof AmazonWebServiceResponse) {
|
||||
final AmazonWebServiceResponse awsResp = (AmazonWebServiceResponse) response.getAwsResponse();
|
||||
span.setTag("aws.requestId", awsResp.getRequestId());
|
||||
}
|
||||
return super.onResponse(span, response);
|
||||
}
|
||||
|
||||
private String remapServiceName(final String serviceName) {
|
||||
if (!serviceNames.containsKey(serviceName)) {
|
||||
serviceNames.put(serviceName, serviceName.replace("Amazon", "").trim());
|
||||
}
|
||||
return serviceNames.get(serviceName);
|
||||
}
|
||||
|
||||
private String remapOperationName(final Class<?> awsOperation) {
|
||||
if (!operationNames.containsKey(awsOperation)) {
|
||||
operationNames.put(awsOperation, awsOperation.getSimpleName().replace("Request", ""));
|
||||
}
|
||||
return operationNames.get(awsOperation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String service() {
|
||||
return COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] instrumentationNames() {
|
||||
return new String[] {"aws-sdk"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String component() {
|
||||
return COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(final Request request) {
|
||||
return request.getHttpMethod().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String url(final Request request) {
|
||||
return request.getEndpoint().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String hostname(final Request request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer port(final Request request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer status(final Response response) {
|
||||
return response.getHttpResponse().getStatusCode();
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright 2017-2018 The OpenTracing Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package datadog.trace.instrumentation.aws.v0;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
|
||||
import com.amazonaws.AmazonWebServiceResponse;
|
||||
import com.amazonaws.Request;
|
||||
import com.amazonaws.Response;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
class SpanDecorator {
|
||||
static final String COMPONENT_NAME = "java-aws-sdk";
|
||||
|
||||
private static final Map<String, String> SERVICE_NAMES = new ConcurrentHashMap<>();
|
||||
private static final Map<Class, String> OPERATION_NAMES = new ConcurrentHashMap<>();
|
||||
|
||||
static void onRequest(final Request<?> request, final Span span) {
|
||||
Tags.COMPONENT.set(span, COMPONENT_NAME);
|
||||
Tags.HTTP_METHOD.set(span, request.getHttpMethod().name());
|
||||
Tags.HTTP_URL.set(span, request.getEndpoint().toString());
|
||||
|
||||
final String awsServiceName = request.getServiceName();
|
||||
final Class<?> awsOperation = request.getOriginalRequest().getClass();
|
||||
|
||||
span.setTag("aws.agent", COMPONENT_NAME);
|
||||
span.setTag("aws.service", awsServiceName);
|
||||
span.setTag("aws.operation", awsOperation.getSimpleName());
|
||||
span.setTag("aws.endpoint", request.getEndpoint().toString());
|
||||
|
||||
span.setTag(DDTags.SERVICE_NAME, COMPONENT_NAME);
|
||||
span.setTag(
|
||||
DDTags.RESOURCE_NAME,
|
||||
remapServiceName(awsServiceName) + "." + remapOperationName(awsOperation));
|
||||
span.setTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT);
|
||||
}
|
||||
|
||||
static void onResponse(final Response response, final Span span) {
|
||||
Tags.HTTP_STATUS.set(span, response.getHttpResponse().getStatusCode());
|
||||
if (response.getAwsResponse() instanceof AmazonWebServiceResponse) {
|
||||
final AmazonWebServiceResponse awsResp = (AmazonWebServiceResponse) response.getAwsResponse();
|
||||
span.setTag("aws.requestId", awsResp.getRequestId());
|
||||
}
|
||||
}
|
||||
|
||||
static void onError(final Throwable throwable, final Span span) {
|
||||
Tags.ERROR.set(span, Boolean.TRUE);
|
||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
||||
}
|
||||
|
||||
private static String remapServiceName(final String serviceName) {
|
||||
if (!SERVICE_NAMES.containsKey(serviceName)) {
|
||||
SERVICE_NAMES.put(serviceName, serviceName.replace("Amazon", "").trim());
|
||||
}
|
||||
return SERVICE_NAMES.get(serviceName);
|
||||
}
|
||||
|
||||
private static String remapOperationName(final Class<?> awsOperation) {
|
||||
if (!OPERATION_NAMES.containsKey(awsOperation)) {
|
||||
OPERATION_NAMES.put(awsOperation, awsOperation.getSimpleName().replace("Request", ""));
|
||||
}
|
||||
return OPERATION_NAMES.get(awsOperation);
|
||||
}
|
||||
}
|
|
@ -19,39 +19,19 @@ import com.amazonaws.Response;
|
|||
import com.amazonaws.handlers.HandlerContextKey;
|
||||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.Tracer;
|
||||
import io.opentracing.propagation.Format;
|
||||
import io.opentracing.propagation.TextMapInjectAdapter;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
|
||||
/** 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.
|
||||
private static final HandlerContextKey<Scope> SCOPE_CONTEXT_KEY =
|
||||
new HandlerContextKey<>("DatadogScope");
|
||||
|
||||
private final SpanContext parentContext; // for Async Client
|
||||
private final Tracer tracer;
|
||||
|
||||
public TracingRequestHandler(final Tracer tracer) {
|
||||
parentContext = null;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of Async Client: beforeRequest runs in separate thread therefore we need to inject
|
||||
* parent context to build chain
|
||||
*
|
||||
* @param parentContext parent context
|
||||
*/
|
||||
public TracingRequestHandler(final SpanContext parentContext, final Tracer tracer) {
|
||||
this.parentContext = parentContext;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmazonWebServiceRequest beforeMarshalling(final AmazonWebServiceRequest request) {
|
||||
return request;
|
||||
|
@ -60,23 +40,17 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void beforeRequest(final Request<?> request) {
|
||||
// Note: not setting Component tag here because it is always set by SpanDecorator
|
||||
final Tracer.SpanBuilder spanBuilder =
|
||||
tracer.buildSpan("aws.command").withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT);
|
||||
|
||||
if (parentContext != null) {
|
||||
spanBuilder.asChildOf(parentContext);
|
||||
}
|
||||
|
||||
final Scope scope = spanBuilder.startActive(true);
|
||||
SpanDecorator.onRequest(request, scope.span());
|
||||
final Scope scope = GlobalTracer.get().buildSpan("aws.command").startActive(true);
|
||||
AwsSdkClientDecorator.INSTANCE.afterStart(scope.span());
|
||||
AwsSdkClientDecorator.INSTANCE.onRequest(scope.span(), request);
|
||||
|
||||
// We inject headers at aws-client level because aws requests may be signed and adding headers
|
||||
// on http-client level may break signature.
|
||||
tracer.inject(
|
||||
scope.span().context(),
|
||||
Format.Builtin.HTTP_HEADERS,
|
||||
new TextMapInjectAdapter(request.getHeaders()));
|
||||
GlobalTracer.get()
|
||||
.inject(
|
||||
scope.span().context(),
|
||||
Format.Builtin.HTTP_HEADERS,
|
||||
new TextMapInjectAdapter(request.getHeaders()));
|
||||
|
||||
request.addHandlerContext(SCOPE_CONTEXT_KEY, scope);
|
||||
}
|
||||
|
@ -85,7 +59,8 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
@Override
|
||||
public void afterResponse(final Request<?> request, final Response<?> response) {
|
||||
final Scope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
SpanDecorator.onResponse(response, scope.span());
|
||||
AwsSdkClientDecorator.INSTANCE.onResponse(scope.span(), response);
|
||||
AwsSdkClientDecorator.INSTANCE.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
}
|
||||
|
||||
|
@ -93,7 +68,8 @@ public class TracingRequestHandler extends RequestHandler2 {
|
|||
@Override
|
||||
public void afterError(final Request<?> request, final Response<?> response, final Exception e) {
|
||||
final Scope scope = request.getHandlerContext(SCOPE_CONTEXT_KEY);
|
||||
SpanDecorator.onError(e, scope.span());
|
||||
AwsSdkClientDecorator.INSTANCE.onError(scope.span(), e);
|
||||
AwsSdkClientDecorator.INSTANCE.beforeFinish(scope.span());
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,12 @@ public abstract class AbstractAwsClientInstrumentation extends Instrumenter.Defa
|
|||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
AwsClientInstrumentation.class.getPackage().getName() + ".TracingExecutionInterceptor",
|
||||
AwsClientInstrumentation.class.getPackage().getName()
|
||||
+ ".TracingExecutionInterceptor$InjectAdapter"
|
||||
"datadog.trace.agent.decorator.BaseDecorator",
|
||||
"datadog.trace.agent.decorator.ClientDecorator",
|
||||
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||
packageName + ".AwsSdkClientDecorator",
|
||||
packageName + ".TracingExecutionInterceptor",
|
||||
packageName + ".TracingExecutionInterceptor$InjectAdapter"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package datadog.trace.instrumentation.aws.v2;
|
||||
|
||||
import datadog.trace.agent.decorator.HttpClientDecorator;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Span;
|
||||
import software.amazon.awssdk.awscore.AwsResponse;
|
||||
import software.amazon.awssdk.core.SdkResponse;
|
||||
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
|
||||
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
|
||||
import software.amazon.awssdk.http.SdkHttpRequest;
|
||||
import software.amazon.awssdk.http.SdkHttpResponse;
|
||||
|
||||
class AwsSdkClientDecorator extends HttpClientDecorator<SdkHttpRequest, SdkHttpResponse> {
|
||||
public static final AwsSdkClientDecorator INSTANCE = new AwsSdkClientDecorator();
|
||||
|
||||
static final String COMPONENT_NAME = "java-aws-sdk";
|
||||
|
||||
public Span onAttributes(final Span span, final ExecutionAttributes attributes) {
|
||||
|
||||
final String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
|
||||
final String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
|
||||
|
||||
// Resource Name has to be set after the HTTP_URL because otherwise decorators overwrite it
|
||||
span.setTag(DDTags.RESOURCE_NAME, awsServiceName + "." + awsOperation);
|
||||
|
||||
span.setTag("aws.agent", COMPONENT_NAME);
|
||||
span.setTag("aws.service", awsServiceName);
|
||||
span.setTag("aws.operation", awsOperation);
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
// Not overriding the super. Should call both with each type of response.
|
||||
public Span onResponse(final Span span, final SdkResponse response) {
|
||||
if (response instanceof AwsResponse) {
|
||||
span.setTag("aws.requestId", ((AwsResponse) response).responseMetadata().requestId());
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String service() {
|
||||
return COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] instrumentationNames() {
|
||||
return new String[] {"aws-sdk"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String component() {
|
||||
return COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(final SdkHttpRequest request) {
|
||||
return request.method().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String url(final SdkHttpRequest request) {
|
||||
return request.protocol()
|
||||
+ "://"
|
||||
+ request.host()
|
||||
+ ":"
|
||||
+ request.port()
|
||||
+ request.encodedPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String hostname(final SdkHttpRequest request) {
|
||||
return request.host();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer port(final SdkHttpRequest request) {
|
||||
return request.port();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer status(final SdkHttpResponse response) {
|
||||
return response.statusCode();
|
||||
}
|
||||
}
|
|
@ -13,44 +13,31 @@
|
|||
*/
|
||||
package datadog.trace.instrumentation.aws.v2;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.context.TraceScope;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.Tracer;
|
||||
import io.opentracing.propagation.Format;
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import software.amazon.awssdk.awscore.AwsResponse;
|
||||
import software.amazon.awssdk.core.SdkResponse;
|
||||
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
|
||||
import software.amazon.awssdk.core.interceptor.Context;
|
||||
import software.amazon.awssdk.core.interceptor.ExecutionAttribute;
|
||||
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
|
||||
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
|
||||
import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
|
||||
import software.amazon.awssdk.http.SdkHttpRequest;
|
||||
|
||||
/** AWS request execution interceptor */
|
||||
public class TracingExecutionInterceptor implements ExecutionInterceptor {
|
||||
|
||||
private static final TracingExecutionInterceptor INSTANCE = new TracingExecutionInterceptor();
|
||||
// Note: it looks like this lambda doesn't get generated as a separate class file so we do not
|
||||
// need to inject helper for it.
|
||||
private static final Consumer<ClientOverrideConfiguration.Builder>
|
||||
OVERRIDE_CONFIGURATION_CONSUMER = builder -> builder.addExecutionInterceptor(INSTANCE);
|
||||
|
||||
static final String COMPONENT_NAME = "java-aws-sdk";
|
||||
OVERRIDE_CONFIGURATION_CONSUMER =
|
||||
builder -> builder.addExecutionInterceptor(new TracingExecutionInterceptor());
|
||||
|
||||
private static final ExecutionAttribute<Span> SPAN_ATTRIBUTE =
|
||||
new ExecutionAttribute<>("DatadogSpan");
|
||||
|
@ -58,16 +45,9 @@ public class TracingExecutionInterceptor implements ExecutionInterceptor {
|
|||
@Override
|
||||
public void beforeExecution(
|
||||
final Context.BeforeExecution context, final ExecutionAttributes executionAttributes) {
|
||||
final Tracer tracer = GlobalTracer.get();
|
||||
|
||||
final Tracer.SpanBuilder builder =
|
||||
tracer
|
||||
.buildSpan("aws.command")
|
||||
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
|
||||
.withTag(Tags.COMPONENT.getKey(), COMPONENT_NAME)
|
||||
.withTag(DDTags.SERVICE_NAME, COMPONENT_NAME)
|
||||
.withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT);
|
||||
executionAttributes.putAttribute(SPAN_ATTRIBUTE, builder.start());
|
||||
final Span span = GlobalTracer.get().buildSpan("aws.command").start();
|
||||
AwsSdkClientDecorator.INSTANCE.afterStart(span);
|
||||
executionAttributes.putAttribute(SPAN_ATTRIBUTE, span);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,35 +56,8 @@ public class TracingExecutionInterceptor implements ExecutionInterceptor {
|
|||
final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
|
||||
final SdkHttpRequest httpRequest = context.httpRequest();
|
||||
|
||||
Tags.HTTP_METHOD.set(span, httpRequest.method().name());
|
||||
|
||||
try {
|
||||
final URI requestUri = httpRequest.getUri();
|
||||
final String uri =
|
||||
new URI(
|
||||
requestUri.getScheme(),
|
||||
null,
|
||||
requestUri.getHost(),
|
||||
requestUri.getPort(),
|
||||
requestUri.getPath(),
|
||||
null,
|
||||
null)
|
||||
.toString();
|
||||
Tags.HTTP_URL.set(span, uri);
|
||||
} catch (final URISyntaxException e) {
|
||||
Tags.HTTP_URL.set(span, "failed-to-parse");
|
||||
}
|
||||
final String awsServiceName =
|
||||
executionAttributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
|
||||
final String awsOperation =
|
||||
executionAttributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
|
||||
|
||||
// Resource Name has to be set after the HTTP_URL because otherwise decorators overwrite it
|
||||
span.setTag(DDTags.RESOURCE_NAME, awsServiceName + "." + awsOperation);
|
||||
|
||||
span.setTag("aws.agent", COMPONENT_NAME);
|
||||
span.setTag("aws.service", awsServiceName);
|
||||
span.setTag("aws.operation", awsOperation);
|
||||
AwsSdkClientDecorator.INSTANCE.onRequest(span, httpRequest);
|
||||
AwsSdkClientDecorator.INSTANCE.onAttributes(span, executionAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,23 +85,18 @@ public class TracingExecutionInterceptor implements ExecutionInterceptor {
|
|||
public void afterExecution(
|
||||
final Context.AfterExecution context, final ExecutionAttributes executionAttributes) {
|
||||
final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
|
||||
try {
|
||||
Tags.HTTP_STATUS.set(span, context.httpResponse().statusCode());
|
||||
final SdkResponse response = context.response();
|
||||
if (response instanceof AwsResponse) {
|
||||
span.setTag("aws.requestId", ((AwsResponse) response).responseMetadata().requestId());
|
||||
}
|
||||
} finally {
|
||||
span.finish();
|
||||
}
|
||||
// Call onResponse on both types of responses:
|
||||
AwsSdkClientDecorator.INSTANCE.onResponse(span, context.response());
|
||||
AwsSdkClientDecorator.INSTANCE.onResponse(span, context.httpResponse());
|
||||
AwsSdkClientDecorator.INSTANCE.beforeFinish(span);
|
||||
span.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExecutionFailure(
|
||||
final Context.FailedExecution context, final ExecutionAttributes executionAttributes) {
|
||||
final Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
|
||||
Tags.ERROR.set(span, Boolean.TRUE);
|
||||
span.log(Collections.singletonMap(ERROR_OBJECT, context.exception()));
|
||||
AwsSdkClientDecorator.INSTANCE.onError(span, context.exception());
|
||||
}
|
||||
|
||||
public static Consumer<ClientOverrideConfiguration.Builder> getOverrideConfigurationConsumer() {
|
||||
|
|
|
@ -76,6 +76,8 @@ class AwsClientTest extends AgentTestRunner {
|
|||
"$Tags.HTTP_STATUS.key" 200
|
||||
"$Tags.HTTP_URL.key" expectedUrl
|
||||
"$Tags.HTTP_METHOD.key" "$method"
|
||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||
"$Tags.PEER_PORT.key" server.address.port
|
||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
|
||||
"aws.service" "$service"
|
||||
|
@ -167,6 +169,8 @@ class AwsClientTest extends AgentTestRunner {
|
|||
"$Tags.HTTP_STATUS.key" 200
|
||||
"$Tags.HTTP_URL.key" expectedUrl
|
||||
"$Tags.HTTP_METHOD.key" "$method"
|
||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||
"$Tags.PEER_PORT.key" server.address.port
|
||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
|
||||
"aws.service" "$service"
|
||||
|
|
Loading…
Reference in New Issue