Change aws-sdk client decorators to tracers
MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AWSClientInstrumentation.java
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AWSClientInstrumentation.java
@@ -53,7 +53,7 @@ public final class AWSClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
- packageName + ".AwsSdkClientDecorator",
+ packageName + ".AwsSdkClientTracer",
packageName + ".RequestMeta",
packageName + ".TracingRequestHandler",
};

MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AWSHttpClientInstrumentation.java
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AWSHttpClientInstrumentation.java
package io.opentelemetry.auto.instrumentation.awssdk.v1_11;
-import static io.opentelemetry.auto.instrumentation.awssdk.v1_11.OnErrorDecorator.DECORATE;
+import static io.opentelemetry.auto.instrumentation.awssdk.v1_11.OnErrorTracer.ERROR_TRACER;
import static io.opentelemetry.auto.instrumentation.awssdk.v1_11.RequestMeta.SPAN_SCOPE_PAIR_CONTEXT_KEY;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
@@ -57,7 +57,7 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
- packageName + ".OnErrorDecorator", packageName + ".RequestMeta",
+ packageName + ".OnErrorTracer", packageName + ".RequestMeta",
};
}
@@ -74,14 +74,12 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
@Advice.Argument(value = 0, optional = true) final Request<?> request,
@Advice.Thrown final Throwable throwable) {
if (throwable != null) {
- SpanWithScope spanWithScope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
- if (spanWithScope != null) {
+ SpanWithScope scope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
+ if (scope != null) {
request.addHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY, null);
- Span span = spanWithScope.getSpan();
- DECORATE.onError(span, throwable);
- DECORATE.beforeFinish(span);
- span.end();
- spanWithScope.closeScope();
+ Span span = scope.getSpan();
+ ERROR_TRACER.endExceptionally(span, throwable);
+ scope.closeScope();
}
}
}
@@ -112,14 +110,12 @@ public class AWSHttpClientInstrumentation extends Instrumenter.Default {
@Advice.FieldValue("request") final Request<?> request,
@Advice.Thrown final Throwable throwable) {
if (throwable != null) {
- SpanWithScope spanWithScope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
- if (spanWithScope != null) {
+ SpanWithScope scope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
+ if (scope != null) {
request.addHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY, null);
- Span span = spanWithScope.getSpan();
- DECORATE.onError(span, throwable);
- DECORATE.beforeFinish(span);
- span.end();
- spanWithScope.closeScope();
+ Span span = scope.getSpan();
+ ERROR_TRACER.endExceptionally(span, throwable);
+ scope.closeScope();
}
}
}

RENAME
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AwsSdkClientDecorator.java
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java
@@ -20,14 +20,15 @@ import com.amazonaws.AmazonWebServiceRequest;
import com.amazonaws.AmazonWebServiceResponse;
import com.amazonaws.Request;
import com.amazonaws.Response;
-import io.opentelemetry.instrumentation.api.decorator.HttpClientDecorator;
+import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
+import io.opentelemetry.instrumentation.api.decorator.HttpClientTracer;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
import io.opentelemetry.trace.Span;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-public class AwsSdkClientDecorator extends HttpClientDecorator<Request<?>, Response<?>> {
+public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Response<?>> {
static final String COMPONENT_NAME = "java-aws-sdk";
@@ -35,8 +36,7 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<Request<?>, Respo
private final Map<Class, String> operationNames = new ConcurrentHashMap<>();
private final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore;
- public AwsSdkClientDecorator(
- final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore) {
+ public AwsSdkClientTracer(final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore) {
this.contextStore = contextStore;
}
@@ -80,7 +80,7 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<Request<?>, Respo
@Override
public Span onResponse(final Span span, final Response<?> response) {
- if (response.getAwsResponse() instanceof AmazonWebServiceResponse) {
+ if (response != null && response.getAwsResponse() instanceof AmazonWebServiceResponse) {
AmazonWebServiceResponse awsResp = (AmazonWebServiceResponse) response.getAwsResponse();
span.setAttribute("aws.requestId", awsResp.getRequestId());
}
@@ -125,4 +125,14 @@ public class AwsSdkClientDecorator extends HttpClientDecorator<Request<?>, Respo
protected String responseHeader(Response<?> response, String name) {
return response.getHttpResponse().getHeaders().get(name);
}
+
+ @Override
+ protected Setter<Request<?>> getSetter() {
+ return null;
+ }
+
+ @Override
+ protected String getInstrumentationName() {
+ return "io.opentelemetry.auto.aws-sdk-1.11";
+ }
}

RENAME
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/OnErrorDecorator.java
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/OnErrorTracer.java
package io.opentelemetry.auto.instrumentation.awssdk.v1_11;
-import io.opentelemetry.instrumentation.api.decorator.BaseDecorator;
+import io.opentelemetry.instrumentation.api.decorator.BaseTracer;
-public class OnErrorDecorator extends BaseDecorator {
- public static final OnErrorDecorator DECORATE = new OnErrorDecorator();
+public class OnErrorTracer extends BaseTracer {
+ public static final OnErrorTracer ERROR_TRACER = new OnErrorTracer();
+
+ @Override
+ protected String getInstrumentationName() {
+ return "io.opentelemetry.auto.aws-sdk-1.11-error";
+ }
}

MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/TracingRequestHandler.java
instrumentation/aws-sdk/aws-sdk-1.11/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v1_11/TracingRequestHandler.java
package io.opentelemetry.auto.instrumentation.awssdk.v1_11;
import static io.opentelemetry.auto.instrumentation.awssdk.v1_11.RequestMeta.SPAN_SCOPE_PAIR_CONTEXT_KEY;
+import static io.opentelemetry.context.ContextUtils.withScopedContext;
+import static io.opentelemetry.instrumentation.api.decorator.ClientDecorator.currentContextWith;
import com.amazonaws.AmazonWebServiceRequest;
import com.amazonaws.Request;
import com.amazonaws.Response;
import com.amazonaws.handlers.RequestHandler2;
-import io.opentelemetry.OpenTelemetry;
-import io.opentelemetry.context.ContextUtils;
-import io.opentelemetry.instrumentation.api.decorator.ClientDecorator;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
import io.opentelemetry.trace.Span;
-import io.opentelemetry.trace.Tracer;
/** Tracing Request Handler */
public class TracingRequestHandler extends RequestHandler2 {
- private static final Tracer TRACER =
- OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.aws-sdk-1.11");
- private final AwsSdkClientDecorator decorate;
+ private final AwsSdkClientTracer tracer;
public TracingRequestHandler(
final ContextStore<AmazonWebServiceRequest, RequestMeta> contextStore) {
- decorate = new AwsSdkClientDecorator(contextStore);
+ tracer = new AwsSdkClientTracer(contextStore);
}
@Override
@@ -49,38 +45,29 @@ public class TracingRequestHandler extends RequestHandler2 {
@Override
public void beforeRequest(final Request<?> request) {
- Span span = decorate.getOrCreateSpan(request, TRACER);
- decorate.afterStart(span);
- decorate.onRequest(span, request);
+ Span span = tracer.startSpan(request);
request.addHandlerContext(
SPAN_SCOPE_PAIR_CONTEXT_KEY,
- new SpanWithScope(
- span, ContextUtils.withScopedContext(ClientDecorator.currentContextWith(span))));
+ new SpanWithScope(span, withScopedContext(currentContextWith(span))));
}
@Override
public void afterResponse(final Request<?> request, final Response<?> response) {
- SpanWithScope spanWithScope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
- if (spanWithScope != null) {
+ SpanWithScope scope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
+ if (scope != null) {
request.addHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY, null);
- spanWithScope.closeScope();
- Span span = spanWithScope.getSpan();
- decorate.onResponse(span, response);
- decorate.beforeFinish(span);
- span.end();
+ scope.closeScope();
+ tracer.end(scope.getSpan(), response);
}
}
@Override
public void afterError(final Request<?> request, final Response<?> response, final Exception e) {
- SpanWithScope spanWithScope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
- if (spanWithScope != null) {
+ SpanWithScope scope = request.getHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY);
+ if (scope != null) {
request.addHandlerContext(SPAN_SCOPE_PAIR_CONTEXT_KEY, null);
- spanWithScope.closeScope();
- Span span = spanWithScope.getSpan();
- decorate.onError(span, e);
- decorate.beforeFinish(span);
- span.end();
+ scope.closeScope();
+ tracer.endExceptionally(scope.getSpan(), response, e);
}
}
}

MODIFY
instrumentation/aws-sdk/aws-sdk-2.2/auto/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v2_2/AbstractAwsClientInstrumentation.java
instrumentation/aws-sdk/aws-sdk-2.2/auto/src/main/java/io/opentelemetry/auto/instrumentation/awssdk/v2_2/AbstractAwsClientInstrumentation.java
@@ -31,7 +31,7 @@ public abstract class AbstractAwsClientInstrumentation extends Instrumenter.Defa
packageName + ".TracingExecutionInterceptor",
packageName + ".TracingExecutionInterceptor$ScopeHolder",
"io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdk",
- "io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkClientDecorator",
+ "io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkClientTracer",
"io.opentelemetry.instrumentation.awssdk.v2_2.TracingExecutionInterceptor",
};
}

MODIFY
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdk.java
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdk.java
@@ -40,12 +40,12 @@ import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
*/
public class AwsSdk {
- private static final Tracer TRACER =
- OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.aws-sdk-2.2");
+ private static final Tracer tracer =
+ OpenTelemetry.getTracerProvider().get(AwsSdkClientTracer.TRACER.getInstrumentationName());
/** Returns the {@link Tracer} used to instrument the AWS SDK. */
public static Tracer tracer() {
- return TRACER;
+ return tracer;
}
/**

DELETE
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkClientDecorator.java
-/*
- * Copyright The OpenTelemetry 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 io.opentelemetry.instrumentation.awssdk.v2_2;
-
-import io.opentelemetry.instrumentation.api.decorator.HttpClientDecorator;
-import io.opentelemetry.trace.Span;
-import io.opentelemetry.trace.attributes.SemanticAttributes;
-import java.net.URI;
-import software.amazon.awssdk.awscore.AwsResponse;
-import software.amazon.awssdk.core.SdkRequest;
-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.SdkHttpHeaders;
-import software.amazon.awssdk.http.SdkHttpRequest;
-import software.amazon.awssdk.http.SdkHttpResponse;
-
-final class AwsSdkClientDecorator extends HttpClientDecorator<SdkHttpRequest, SdkHttpResponse> {
- static final AwsSdkClientDecorator DECORATE = new AwsSdkClientDecorator();
-
- static final String COMPONENT_NAME = "java-aws-sdk";
-
- Span onSdkRequest(final Span span, final SdkRequest request) {
- // S3
- request
- .getValueForField("Bucket", String.class)
- .ifPresent(name -> span.setAttribute("aws.bucket.name", name));
- // SQS
- request
- .getValueForField("QueueUrl", String.class)
- .ifPresent(name -> span.setAttribute("aws.queue.url", name));
- request
- .getValueForField("QueueName", String.class)
- .ifPresent(name -> span.setAttribute("aws.queue.name", name));
- // Kinesis
- request
- .getValueForField("StreamName", String.class)
- .ifPresent(name -> span.setAttribute("aws.stream.name", name));
- // DynamoDB
- request
- .getValueForField("TableName", String.class)
- .ifPresent(name -> span.setAttribute("aws.table.name", name));
- return span;
- }
-
- String spanName(final ExecutionAttributes attributes) {
- String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
- String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
-
- return awsServiceName + "." + awsOperation;
- }
-
- Span onAttributes(final Span span, final ExecutionAttributes attributes) {
-
- String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
- String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
-
- span.setAttribute("aws.agent", COMPONENT_NAME);
- span.setAttribute("aws.service", awsServiceName);
- span.setAttribute("aws.operation", awsOperation);
-
- return span;
- }
-
- // Certain headers in the request like User-Agent are only available after execution.
- Span afterExecution(final Span span, final SdkHttpRequest request) {
- SemanticAttributes.HTTP_USER_AGENT.set(span, requestHeader(request, USER_AGENT));
- return span;
- }
-
- // Not overriding the super. Should call both with each type of response.
- Span onSdkResponse(final Span span, final SdkResponse response) {
- if (response instanceof AwsResponse) {
- span.setAttribute("aws.requestId", ((AwsResponse) response).responseMetadata().requestId());
- }
- return span;
- }
-
- @Override
- protected String method(final SdkHttpRequest request) {
- return request.method().name();
- }
-
- @Override
- protected URI url(final SdkHttpRequest request) {
- return request.getUri();
- }
-
- @Override
- protected Integer status(final SdkHttpResponse response) {
- return response.statusCode();
- }
-
- @Override
- protected String requestHeader(SdkHttpRequest sdkHttpRequest, String name) {
- return header(sdkHttpRequest, name);
- }
-
- @Override
- protected String responseHeader(SdkHttpResponse sdkHttpResponse, String name) {
- return header(sdkHttpResponse, name);
- }
-
- private static String header(SdkHttpHeaders headers, String name) {
- return headers.firstMatchingHeader(name).orElse(null);
- }
-}

ADD
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkClientTracer.java
+/*
+ * Copyright The OpenTelemetry 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 io.opentelemetry.instrumentation.awssdk.v2_2;
+
+import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
+import io.opentelemetry.instrumentation.api.decorator.HttpClientTracer;
+import io.opentelemetry.trace.DefaultSpan;
+import io.opentelemetry.trace.Span;
+import io.opentelemetry.trace.Span.Kind;
+import io.opentelemetry.trace.Tracer;
+import io.opentelemetry.trace.TracingContextUtils;
+import io.opentelemetry.trace.attributes.SemanticAttributes;
+import java.net.URI;
+import software.amazon.awssdk.http.SdkHttpHeaders;
+import software.amazon.awssdk.http.SdkHttpRequest;
+import software.amazon.awssdk.http.SdkHttpResponse;
+
+final class AwsSdkClientTracer extends HttpClientTracer<SdkHttpRequest, SdkHttpResponse> {
+ static final AwsSdkClientTracer TRACER = new AwsSdkClientTracer();
+
+ // Certain headers in the request like User-Agent are only available after execution.
+ Span afterExecution(final Span span, final SdkHttpRequest request) {
+ SemanticAttributes.HTTP_USER_AGENT.set(span, requestHeader(request, USER_AGENT));
+ return span;
+ }
+
+ @Override
+ protected String method(final SdkHttpRequest request) {
+ return request.method().name();
+ }
+
+ @Override
+ protected URI url(final SdkHttpRequest request) {
+ return request.getUri();
+ }
+
+ @Override
+ protected Integer status(final SdkHttpResponse response) {
+ return response.statusCode();
+ }
+
+ @Override
+ protected String requestHeader(SdkHttpRequest sdkHttpRequest, String name) {
+ return header(sdkHttpRequest, name);
+ }
+
+ @Override
+ protected String responseHeader(SdkHttpResponse sdkHttpResponse, String name) {
+ return header(sdkHttpResponse, name);
+ }
+
+ @Override
+ protected Setter<SdkHttpRequest> getSetter() {
+ return null;
+ }
+
+ private static String header(SdkHttpHeaders headers, String name) {
+ return headers.firstMatchingHeader(name).orElse(null);
+ }
+
+ @Override
+ protected String getInstrumentationName() {
+ return "io.opentelemetry.auto.aws-sdk-2.2";
+ }
+
+ /**
+ * Returns a new client {@link Span} if there is no client {@link Span} in the current {@link
+ * io.grpc.Context }, or an invalid {@link Span} otherwise.
+ */
+ public Span getOrCreateSpan(String name, Tracer tracer) {
+ io.grpc.Context context = io.grpc.Context.current();
+ Span clientSpan = CONTEXT_CLIENT_SPAN_KEY.get(context);
+
+ if (clientSpan != null) {
+ // We don't want to create two client spans for a given client call, suppress inner spans.
+ return DefaultSpan.getInvalid();
+ }
+
+ Span current = TracingContextUtils.getSpan(context);
+ return tracer.spanBuilder(name).setSpanKind(Kind.CLIENT).setParent(current).startSpan();
+ }
+
+ /** This method is overridden to allow other classes in this package to call it. */
+ @Override
+ protected Span onRequest(Span span, SdkHttpRequest sdkHttpRequest) {
+ return super.onRequest(span, sdkHttpRequest);
+ }
+}

MODIFY
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java
package io.opentelemetry.instrumentation.awssdk.v2_2;
-import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkClientDecorator.DECORATE;
+import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkClientTracer.TRACER;
-import io.opentelemetry.instrumentation.api.decorator.ClientDecorator;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Span.Kind;
+import software.amazon.awssdk.awscore.AwsResponse;
+import software.amazon.awssdk.core.SdkRequest;
+import software.amazon.awssdk.core.SdkResponse;
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;
/** AWS request execution interceptor */
final class TracingExecutionInterceptor implements ExecutionInterceptor {
@@ -32,6 +35,8 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
static final ExecutionAttribute<Span> SPAN_ATTRIBUTE =
new ExecutionAttribute<>("io.opentelemetry.auto.Span");
+ static final String COMPONENT_NAME = "java-aws-sdk";
+
private final Kind kind;
TracingExecutionInterceptor(Kind kind) {
@@ -41,9 +46,7 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
@Override
public void beforeExecution(
final Context.BeforeExecution context, final ExecutionAttributes executionAttributes) {
- Span span =
- ClientDecorator.getOrCreateSpan(DECORATE.spanName(executionAttributes), AwsSdk.tracer());
- DECORATE.afterStart(span);
+ Span span = TRACER.getOrCreateSpan(spanName(executionAttributes), AwsSdk.tracer());
executionAttributes.putAttribute(SPAN_ATTRIBUTE, span);
}
@@ -51,11 +54,10 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
public void afterMarshalling(
final Context.AfterMarshalling context, final ExecutionAttributes executionAttributes) {
Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
-
if (span != null) {
- DECORATE.onRequest(span, context.httpRequest());
- DECORATE.onSdkRequest(span, context.request());
- DECORATE.onAttributes(span, executionAttributes);
+ TRACER.onRequest(span, context.httpRequest());
+ onSdkRequest(span, context.request());
+ onAttributes(span, executionAttributes);
}
}
@@ -64,16 +66,10 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
final Context.AfterExecution context, final ExecutionAttributes executionAttributes) {
Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
if (span != null) {
- try {
executionAttributes.putAttribute(SPAN_ATTRIBUTE, null);
- DECORATE.afterExecution(span, context.httpRequest());
- // Call onResponse on both types of responses:
- DECORATE.onSdkResponse(span, context.response());
- DECORATE.onResponse(span, context.httpResponse());
- DECORATE.beforeFinish(span);
- } finally {
- span.end();
- }
+ TRACER.afterExecution(span, context.httpRequest());
+ onSdkResponse(span, context.response());
+ TRACER.end(span, context.httpResponse());
}
}
@@ -82,13 +78,58 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
final Context.FailedExecution context, final ExecutionAttributes executionAttributes) {
Span span = executionAttributes.getAttribute(SPAN_ATTRIBUTE);
if (span != null) {
- try {
executionAttributes.putAttribute(SPAN_ATTRIBUTE, null);
- DECORATE.onError(span, context.exception());
- DECORATE.beforeFinish(span);
- } finally {
- span.end();
+ TRACER.endExceptionally(span, context.exception());
+ }
}
+
+ Span onSdkRequest(final Span span, final SdkRequest request) {
+ // S3
+ request
+ .getValueForField("Bucket", String.class)
+ .ifPresent(name -> span.setAttribute("aws.bucket.name", name));
+ // SQS
+ request
+ .getValueForField("QueueUrl", String.class)
+ .ifPresent(name -> span.setAttribute("aws.queue.url", name));
+ request
+ .getValueForField("QueueName", String.class)
+ .ifPresent(name -> span.setAttribute("aws.queue.name", name));
+ // Kinesis
+ request
+ .getValueForField("StreamName", String.class)
+ .ifPresent(name -> span.setAttribute("aws.stream.name", name));
+ // DynamoDB
+ request
+ .getValueForField("TableName", String.class)
+ .ifPresent(name -> span.setAttribute("aws.table.name", name));
+ return span;
+ }
+
+ String spanName(final ExecutionAttributes attributes) {
+ String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
+ String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
+
+ return awsServiceName + "." + awsOperation;
+ }
+
+ Span onAttributes(final Span span, final ExecutionAttributes attributes) {
+
+ String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
+ String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
+
+ span.setAttribute("aws.agent", COMPONENT_NAME);
+ span.setAttribute("aws.service", awsServiceName);
+ span.setAttribute("aws.operation", awsOperation);
+
+ return span;
+ }
+
+ // Not overriding the super. Should call both with each type of response.
+ Span onSdkResponse(final Span span, final SdkResponse response) {
+ if (response instanceof AwsResponse) {
+ span.setAttribute("aws.requestId", ((AwsResponse) response).responseMetadata().requestId());
}
+ return span;
}
}

MODIFY
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/BaseTracer.java
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/BaseTracer.java
@@ -33,6 +33,11 @@ public abstract class BaseTracer {
public static final Context.Key<Span> CONTEXT_SERVER_SPAN_KEY =
Context.key("opentelemetry-trace-server-span-key");
+ // Keeps track of the client span in a subtree corresponding to a client request.
+ // Visible for testing
+ public static final Context.Key<Span> CONTEXT_CLIENT_SPAN_KEY =
+ Context.key("opentelemetry-trace-auto-client-span-key");
+
protected final Tracer tracer;
public BaseTracer() {

MODIFY
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/DatabaseClientTracer.java
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/DatabaseClientTracer.java
@@ -31,9 +31,6 @@ import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
public abstract class DatabaseClientTracer<CONNECTION, QUERY> extends BaseTracer {
- // Keeps track of the client span for the current trace.
- private static final Context.Key<Span> CONTEXT_CLIENT_SPAN_KEY =
- Context.key("opentelemetry-trace-client-span-key");
private static final String DB_QUERY = "DB Query";

MODIFY
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/HttpClientTracer.java
library-api/src/main/java/io/opentelemetry/instrumentation/api/decorator/HttpClientTracer.java
@@ -87,7 +87,7 @@ public abstract class HttpClientTracer<REQUEST, RESPONSE> extends BaseTracer {
*/
private Span startSpan(REQUEST request, String name) {
Context context = Context.current();
- Span clientSpan = ClientDecorator.CONTEXT_CLIENT_SPAN_KEY.get(context);
+ Span clientSpan = CONTEXT_CLIENT_SPAN_KEY.get(context);
if (clientSpan != null) {
// We don't want to create two client spans for a given client call, suppress inner spans.
@@ -100,7 +100,7 @@ public abstract class HttpClientTracer<REQUEST, RESPONSE> extends BaseTracer {
return span;
}
- private Span onRequest(final Span span, final REQUEST request) {
+ protected Span onRequest(final Span span, final REQUEST request) {
assert span != null;
if (request != null) {
span.setAttribute(SemanticAttributes.HTTP_METHOD.key(), method(request));
@@ -159,11 +159,10 @@ public abstract class HttpClientTracer<REQUEST, RESPONSE> extends BaseTracer {
return span;
}
- private Span onResponse(final Span span, final RESPONSE response) {
+ protected Span onResponse(final Span span, final RESPONSE response) {
assert span != null;
if (response != null) {
Integer status = status(response);
- System.out.println("status: " + status);
if (status != null) {
span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE.key(), status);
span.setStatus(HttpStatusConverter.statusFromHttpStatus(status));
@@ -172,7 +171,7 @@ public abstract class HttpClientTracer<REQUEST, RESPONSE> extends BaseTracer {
return span;
}
- private String spanNameForRequest(final REQUEST request) {
+ protected String spanNameForRequest(final REQUEST request) {
if (request == null) {
return DEFAULT_SPAN_NAME;
}

Change aws-sdk client decorators to tracers (#918)