HTTP client instrumentation cleanup: aws-sdk
MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java
@@ -11,7 +11,7 @@ import com.amazonaws.Request;
import com.amazonaws.Response;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
-import io.opentelemetry.context.propagation.TextMapPropagator.Setter;
+import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;
@@ -31,7 +31,7 @@ public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Request<?>,
public AwsSdkClientTracer() {}
@Override
- public String spanNameForRequest(Request<?> request) {
+ protected String spanNameForRequest(Request<?> request) {
if (request == null) {
return DEFAULT_SPAN_NAME;
}
@@ -111,7 +111,7 @@ public class AwsSdkClientTracer extends HttpClientTracer<Request<?>, Request<?>,
}
@Override
- protected Setter<Request<?>> getSetter() {
+ protected TextMapPropagator.Setter<Request<?>> getSetter() {
return AwsSdkInjectAdapter.INSTANCE;
}

MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestMeta.java
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestMeta.java
@@ -12,7 +12,7 @@ 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<ContextScopePair> CONTEXT_SCOPE_PAIR_CONTEXT_KEY =
- new HandlerContextKey<>(RequestMeta.class.getName() + ".ContextSpanPair");
+ new HandlerContextKey<>(RequestMeta.class.getName() + ".ContextScopePair");
private String bucketName;
private String queueUrl;

MODIFY
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/TracingRequestHandler.java
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/TracingRequestHandler.java
@@ -30,31 +30,33 @@ public class TracingRequestHandler extends RequestHandler2 {
AmazonWebServiceRequest originalRequest = request.getOriginalRequest();
RequestMeta requestMeta = contextStore.get(originalRequest);
Context parentContext = Context.current();
- if (tracer().shouldStartSpan(parentContext)) {
+ if (!tracer().shouldStartSpan(parentContext)) {
+ return;
+ }
Context context = tracer().startSpan(parentContext, request, requestMeta);
Scope scope = context.makeCurrent();
- request.addHandlerContext(
- CONTEXT_SCOPE_PAIR_CONTEXT_KEY, new ContextScopePair(context, scope));
- }
+ request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, new ContextScopePair(context, scope));
}
@Override
public void afterResponse(Request<?> request, Response<?> response) {
ContextScopePair scope = request.getHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY);
- if (scope != null) {
+ if (scope == null) {
+ return;
+ }
request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, null);
scope.closeScope();
tracer().end(scope.getContext(), response);
}
- }
@Override
public void afterError(Request<?> request, Response<?> response, Exception e) {
ContextScopePair scope = request.getHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY);
- if (scope != null) {
+ if (scope == null) {
+ return;
+ }
request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, null);
scope.closeScope();
- tracer().endExceptionally(scope.getContext(), response, e);
- }
+ tracer().endExceptionally(scope.getContext(), e);
}
}

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
@@ -8,8 +8,6 @@ package io.opentelemetry.instrumentation.awssdk.v2_2;
import static io.opentelemetry.instrumentation.awssdk.v2_2.TracingExecutionInterceptor.CONTEXT_ATTRIBUTE;
import io.opentelemetry.api.OpenTelemetry;
-import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
@@ -40,29 +38,17 @@ public class AwsSdk {
/**
* Returns an {@link ExecutionInterceptor} that can be used with an {@link
- * software.amazon.awssdk.http.SdkHttpClient} to trace SDK requests. Spans are created with the
- * kind {@link Kind#CLIENT}. If you also instrument the HTTP calls made by the SDK, e.g., by
- * adding Apache HTTP client or Netty instrumentation, you may want to use {@link
- * #newInterceptor(Kind)} with {@link Kind#INTERNAL} instead.
+ * software.amazon.awssdk.http.SdkHttpClient} to trace SDK requests.
*/
public static ExecutionInterceptor newInterceptor() {
- return newInterceptor(Kind.CLIENT);
+ return new TracingExecutionInterceptor();
}
/**
- * Returns an {@link ExecutionInterceptor} that can be used with an {@link
- * software.amazon.awssdk.http.SdkHttpClient} to trace SDK requests. Spans are created with the
- * provided {@link Kind}.
- */
- public static ExecutionInterceptor newInterceptor(Kind kind) {
- return new TracingExecutionInterceptor(kind);
- }
-
- /**
- * Returns the {@link Span} stored in the {@link ExecutionAttributes}, or {@code null} if there is
- * no span set.
+ * Returns the {@link Context} stored in the {@link ExecutionAttributes}, or {@code null} if there
+ * is no operation set.
*/
- public static Context getContextFromAttributes(ExecutionAttributes attributes) {
+ public static Context getContext(ExecutionAttributes attributes) {
return attributes.getAttribute(CONTEXT_ATTRIBUTE);
}
}

MODIFY
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java
instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java
package io.opentelemetry.instrumentation.awssdk.v2_2;
+import static io.opentelemetry.api.trace.Span.Kind.CLIENT;
+
import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.api.trace.Span.Kind;
-import io.opentelemetry.api.trace.Tracer;
-import io.opentelemetry.api.trace.attributes.SemanticAttributes;
import io.opentelemetry.context.Context;
-import io.opentelemetry.context.propagation.TextMapPropagator.Setter;
-import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
+import io.opentelemetry.context.propagation.TextMapPropagator;
+import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator;
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
import java.net.URI;
+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 AwsSdkHttpClientTracer
- extends HttpClientTracer<SdkHttpRequest, SdkHttpRequest, SdkHttpResponse> {
+ extends HttpClientTracer<SdkHttpRequest, SdkHttpRequest.Builder, SdkHttpResponse> {
private static final AwsSdkHttpClientTracer TRACER = new AwsSdkHttpClientTracer();
@@ -27,10 +28,15 @@ final class AwsSdkHttpClientTracer
return TRACER;
}
- // Certain headers in the request like User-Agent are only available after execution.
- Span afterExecution(Span span, SdkHttpRequest request) {
- span.setAttribute(SemanticAttributes.HTTP_USER_AGENT, requestHeader(request, USER_AGENT));
- return span;
+ public Context startSpan(Context parentContext, ExecutionAttributes attributes) {
+ String spanName = spanName(attributes);
+ Span span =
+ tracer.spanBuilder(spanName).setSpanKind(CLIENT).setParent(parentContext).startSpan();
+ return withClientSpan(parentContext, span);
+ }
+
+ public void inject(Context context, SdkHttpRequest.Builder builder) {
+ AwsXRayPropagator.getInstance().inject(context, builder, getSetter());
}
@Override
@@ -59,8 +65,8 @@ final class AwsSdkHttpClientTracer
}
@Override
- protected Setter<SdkHttpRequest> getSetter() {
- return null;
+ protected TextMapPropagator.Setter<SdkHttpRequest.Builder> getSetter() {
+ return AwsSdkInjectAdapter.INSTANCE;
}
private static String header(SdkHttpHeaders headers, String name) {
@@ -78,9 +84,9 @@ final class AwsSdkHttpClientTracer
super.onRequest(span, sdkHttpRequest);
}
- public Context startSpan(Context parentContext, String name, Tracer tracer, Kind kind) {
- Span clientSpan =
- tracer.spanBuilder(name).setSpanKind(kind).setParent(parentContext).startSpan();
- return parentContext.with(clientSpan).with(BaseTracer.CONTEXT_CLIENT_SPAN_KEY, clientSpan);
+ private static String spanName(ExecutionAttributes attributes) {
+ String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
+ String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
+ return awsServiceName + "." + awsOperation;
}
}

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.AwsSdk.getContextFromAttributes;
+import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdk.getContext;
import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkHttpClientTracer.tracer;
import static io.opentelemetry.instrumentation.awssdk.v2_2.RequestType.ofSdkRequest;
import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.api.trace.Span.Kind;
+import io.opentelemetry.api.trace.attributes.SemanticAttributes;
import io.opentelemetry.context.Scope;
-import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
@@ -61,12 +60,6 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
return result;
}
- private final Kind kind;
-
- TracingExecutionInterceptor(Kind kind) {
- this.kind = kind;
- }
-
@Nullable
private SdkRequestDecorator decorator(ExecutionAttributes executionAttributes) {
RequestType type = getTypeFromAttributes(executionAttributes);
@@ -80,12 +73,12 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
@Override
public void beforeExecution(
Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
- io.opentelemetry.context.Context parentContext = io.opentelemetry.context.Context.current();
- if (!tracer().shouldStartSpan(parentContext)) {
+ io.opentelemetry.context.Context parentOtelContext = io.opentelemetry.context.Context.current();
+ if (!tracer().shouldStartSpan(parentOtelContext)) {
return;
}
io.opentelemetry.context.Context otelContext =
- tracer().startSpan(parentContext, spanName(executionAttributes), AwsSdk.tracer(), kind);
+ tracer().startSpan(parentOtelContext, executionAttributes);
executionAttributes.putAttribute(CONTEXT_ATTRIBUTE, otelContext);
RequestType type = ofSdkRequest(context.request());
if (type != null) {
@@ -103,20 +96,20 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
@Override
public SdkHttpRequest modifyHttpRequest(
Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
- io.opentelemetry.context.Context otelContext = getContextFromAttributes(executionAttributes);
+ io.opentelemetry.context.Context otelContext = getContext(executionAttributes);
if (otelContext == null) {
return context.httpRequest();
}
SdkHttpRequest.Builder builder = context.httpRequest().toBuilder();
- AwsXRayPropagator.getInstance().inject(otelContext, builder, AwsSdkInjectAdapter.INSTANCE);
+ tracer().inject(otelContext, builder);
return builder.build();
}
@Override
public void afterMarshalling(
Context.AfterMarshalling context, ExecutionAttributes executionAttributes) {
- io.opentelemetry.context.Context otelContext = getContextFromAttributes(executionAttributes);
+ io.opentelemetry.context.Context otelContext = getContext(executionAttributes);
if (otelContext == null) {
return;
}
@@ -160,14 +153,18 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
if (scope != null) {
scope.close();
}
- io.opentelemetry.context.Context otelContext = getContextFromAttributes(executionAttributes);
- if (otelContext != null) {
+ io.opentelemetry.context.Context otelContext = getContext(executionAttributes);
clearAttributes(executionAttributes);
Span span = Span.fromContext(otelContext);
- tracer().afterExecution(span, context.httpRequest());
+ onUserAgentHeaderAvailable(span, context.httpRequest());
onSdkResponse(span, context.response());
tracer().end(otelContext, context.httpResponse());
}
+
+ // Certain headers in the request like User-Agent are only available after execution.
+ private void onUserAgentHeaderAvailable(Span span, SdkHttpRequest request) {
+ span.setAttribute(
+ SemanticAttributes.HTTP_USER_AGENT, tracer().requestHeader(request, "User-Agent"));
}
private void onSdkResponse(Span span, SdkResponse response) {
@@ -179,22 +176,13 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
@Override
public void onExecutionFailure(
Context.FailedExecution context, ExecutionAttributes executionAttributes) {
- io.opentelemetry.context.Context otelContext = getContextFromAttributes(executionAttributes);
- if (otelContext != null) {
+ io.opentelemetry.context.Context otelContext = getContext(executionAttributes);
clearAttributes(executionAttributes);
tracer().endExceptionally(otelContext, context.exception());
}
- }
private void clearAttributes(ExecutionAttributes executionAttributes) {
executionAttributes.putAttribute(CONTEXT_ATTRIBUTE, null);
executionAttributes.putAttribute(REQUEST_TYPE_ATTRIBUTE, null);
}
-
- private String spanName(ExecutionAttributes attributes) {
- String awsServiceName = attributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
- String awsOperation = attributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
-
- return awsServiceName + "." + awsOperation;
- }
}

HTTP client instrumentation cleanup: aws-sdk (#1911)