diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java index ee157654e9..92d89c20fb 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkClientTracer.java +++ b/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, 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, } @Override - protected Setter> getSetter() { + protected TextMapPropagator.Setter> getSetter() { return AwsSdkInjectAdapter.INSTANCE; } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestMeta.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestMeta.java index a42b4cbcba..5b91ad988d 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestMeta.java +++ b/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 CONTEXT_SCOPE_PAIR_CONTEXT_KEY = - new HandlerContextKey<>(RequestMeta.class.getName() + ".ContextSpanPair"); + new HandlerContextKey<>(RequestMeta.class.getName() + ".ContextScopePair"); private String bucketName; private String queueUrl; diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/TracingRequestHandler.java index ce16ca9dfa..1fd2e28e47 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/TracingRequestHandler.java +++ b/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)) { - Context context = tracer().startSpan(parentContext, request, requestMeta); - Scope scope = context.makeCurrent(); - request.addHandlerContext( - CONTEXT_SCOPE_PAIR_CONTEXT_KEY, new ContextScopePair(context, scope)); + 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)); } @Override public void afterResponse(Request request, Response response) { ContextScopePair scope = request.getHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY); - if (scope != null) { - request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, null); - scope.closeScope(); - tracer().end(scope.getContext(), response); + 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) { - request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, null); - scope.closeScope(); - tracer().endExceptionally(scope.getContext(), response, e); + if (scope == null) { + return; } + request.addHandlerContext(CONTEXT_SCOPE_PAIR_CONTEXT_KEY, null); + scope.closeScope(); + tracer().endExceptionally(scope.getContext(), e); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdk.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdk.java index 4148850017..9bfd07d8da 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdk.java +++ b/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}. + * Returns the {@link Context} stored in the {@link ExecutionAttributes}, or {@code null} if there + * is no operation set. */ - 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. - */ - public static Context getContextFromAttributes(ExecutionAttributes attributes) { + public static Context getContext(ExecutionAttributes attributes) { return attributes.getAttribute(CONTEXT_ATTRIBUTE); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java index bb760662d8..f49de3efe2 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AwsSdkHttpClientTracer.java @@ -5,21 +5,22 @@ 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 { + extends HttpClientTracer { 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 getSetter() { - return null; + protected TextMapPropagator.Setter 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; } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java index 3823e75a1d..cea0103935 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/TracingExecutionInterceptor.java @@ -5,14 +5,13 @@ 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) { - clearAttributes(executionAttributes); - Span span = Span.fromContext(otelContext); - tracer().afterExecution(span, context.httpRequest()); - onSdkResponse(span, context.response()); - tracer().end(otelContext, context.httpResponse()); - } + io.opentelemetry.context.Context otelContext = getContext(executionAttributes); + clearAttributes(executionAttributes); + Span span = Span.fromContext(otelContext); + 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) { - clearAttributes(executionAttributes); - tracer().endExceptionally(otelContext, context.exception()); - } + 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; - } }