-
Notifications
You must be signed in to change notification settings - Fork 873
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aws-sdk-1.1: Copy SQS plugin/NoMuzzle approach from 2.2 (#8866)
Co-authored-by: Mateusz Rzeszutek <[email protected]>
- Loading branch information
Showing
14 changed files
with
311 additions
and
266 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...avaagent/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/SqsAdviceBridge.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.awssdk.v1_11; | ||
|
||
public final class SqsAdviceBridge { | ||
private SqsAdviceBridge() {} | ||
|
||
public static void referenceForMuzzleOnly() { | ||
throw new UnsupportedOperationException( | ||
SqsImpl.class.getName() + " referencing for muzzle, should never be actually called"); | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
...telemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11; | ||
|
||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; | ||
import static java.util.Collections.singletonList; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
|
||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import java.util.List; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
// TODO: Copy & paste with only trivial adaptions from v2 | ||
abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule { | ||
|
||
protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationName) { | ||
super("aws-sdk", "aws-sdk-1.11", additionalInstrumentationName); | ||
} | ||
|
||
@Override | ||
public boolean isHelperClass(String className) { | ||
return className.startsWith("io.opentelemetry.contrib.awsxray."); | ||
} | ||
|
||
@Override | ||
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() { | ||
// We don't actually transform it but want to make sure we only apply the instrumentation when | ||
// our key dependency is present. | ||
return hasClassesNamed("com.amazonaws.AmazonWebServiceClient"); | ||
} | ||
|
||
@Override | ||
public List<TypeInstrumentation> typeInstrumentations() { | ||
return singletonList(new ResourceInjectingTypeInstrumentation()); | ||
} | ||
|
||
abstract void doTransform(TypeTransformer transformer); | ||
|
||
// A type instrumentation is needed to trigger resource injection. | ||
public class ResourceInjectingTypeInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
// This is essentially the entry point of the AWS SDK, all clients implement it. We can ensure | ||
// our interceptor service definition is injected as early as possible if we typematch against | ||
// it. | ||
return named("com.amazonaws.AmazonWebServiceClient"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
doTransform(transformer); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
...ava/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.awssdk.v1_11; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.none; | ||
|
||
import com.google.auto.service.AutoService; | ||
import io.opentelemetry.instrumentation.awssdk.v1_11.SqsAdviceBridge; | ||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import net.bytebuddy.asm.Advice; | ||
|
||
@AutoService(InstrumentationModule.class) | ||
public class SqsInstrumentationModule extends AbstractAwsSdkInstrumentationModule { | ||
|
||
public SqsInstrumentationModule() { | ||
super("aws-sdk-1.11-sqs"); | ||
} | ||
|
||
@Override | ||
public void doTransform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
none(), SqsInstrumentationModule.class.getName() + "$RegisterAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class RegisterAdvice { | ||
@Advice.OnMethodExit(suppress = Throwable.class) | ||
public static void onExit() { | ||
// (indirectly) using SqsImpl class here to make sure it is available from SqsAccess | ||
// (injected into app classloader) and checked by Muzzle | ||
SqsAdviceBridge.referenceForMuzzleOnly(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...1/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/PluginImplUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.awssdk.v1_11; | ||
|
||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
final class PluginImplUtil { // TODO: Copy & paste from v2 | ||
private PluginImplUtil() {} | ||
|
||
private static final Logger logger = Logger.getLogger(PluginImplUtil.class.getName()); | ||
|
||
/** | ||
* Check if the given {@code moduleNameImpl} is present. | ||
* | ||
* <p>For library instrumentations, the Impls will always be available but might fail to | ||
* load/link/initialize if the corresponding SDK classes are not on the class path. For javaagent, | ||
* the Impl is available only when the corresponding InstrumentationModule was successfully | ||
* applied (muzzle passed). | ||
* | ||
* <p>Note that an present-but-incompatible library can only be reliably detected by Muzzle. In | ||
* library-mode, users need to ensure they are using a compatible SDK (component) versions | ||
* themselves. | ||
* | ||
* @param implSimpleClassName The simple name of the impl class, e.g. {@code "SqsImpl"}. * | ||
*/ | ||
static boolean isImplPresent(String implSimpleClassName) { | ||
// Computing the full name dynamically name here because library instrumentation classes are | ||
// relocated when embedded in the agent. | ||
// We use getName().replace() instead of getPackage() because the latter is not guaranteed to | ||
// work in all cases (e.g., we might be loaded into a custom classloader that doesn't handle it) | ||
String implFullClassName = | ||
PluginImplUtil.class.getName().replace(".PluginImplUtil", "." + implSimpleClassName); | ||
try { | ||
Class.forName(implFullClassName); | ||
return true; | ||
} catch (ClassNotFoundException | LinkageError e) { | ||
// ClassNotFoundException will happen when muzzle disabled us in javaagent mode; LinkageError | ||
// (most likely a NoClassDefFoundError, potentially wrapped in an ExceptionInInitializerError) | ||
// should be thrown when the class is loaded in library mode (where the Impl class itself can | ||
// always be found) but a dependency failed to load (most likely because the corresponding SDK | ||
// dependency is not on the class path). | ||
logger.log( | ||
Level.FINE, | ||
e, | ||
() -> | ||
implFullClassName | ||
+ " not present. " | ||
+ "Most likely, corresponding SDK component is either not on classpath or incompatible."); | ||
return false; | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...k-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/SqsAccess.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.awssdk.v1_11; | ||
|
||
import com.amazonaws.AmazonWebServiceRequest; | ||
import com.amazonaws.Request; | ||
import com.amazonaws.Response; | ||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||
import io.opentelemetry.javaagent.tooling.muzzle.NoMuzzle; | ||
|
||
final class SqsAccess { | ||
private SqsAccess() {} | ||
|
||
private static final boolean enabled = PluginImplUtil.isImplPresent("SqsImpl"); | ||
|
||
@NoMuzzle | ||
static boolean afterResponse( | ||
Request<?> request, | ||
Response<?> response, | ||
Instrumenter<Request<?>, Response<?>> consumerInstrumenter) { | ||
return enabled && SqsImpl.afterResponse(request, response, consumerInstrumenter); | ||
} | ||
|
||
@NoMuzzle | ||
static boolean beforeMarshalling(AmazonWebServiceRequest request) { | ||
return enabled && SqsImpl.beforeMarshalling(request); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/SqsImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.awssdk.v1_11; | ||
|
||
import com.amazonaws.AmazonWebServiceRequest; | ||
import com.amazonaws.Request; | ||
import com.amazonaws.Response; | ||
import com.amazonaws.services.sqs.AmazonSQS; | ||
import com.amazonaws.services.sqs.model.Message; | ||
import com.amazonaws.services.sqs.model.ReceiveMessageRequest; | ||
import com.amazonaws.services.sqs.model.ReceiveMessageResult; | ||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||
|
||
final class SqsImpl { | ||
static { | ||
// Force loading of SQS class; this ensures that an exception is thrown at this point when the | ||
// SQS library is not present, which will cause SqsAccess to have enabled=false in library mode. | ||
@SuppressWarnings("unused") | ||
String ensureLoadedDummy = AmazonSQS.class.getName(); | ||
} | ||
|
||
private SqsImpl() {} | ||
|
||
static boolean afterResponse( | ||
Request<?> request, | ||
Response<?> response, | ||
Instrumenter<Request<?>, Response<?>> consumerInstrumenter) { | ||
if (response.getAwsResponse() instanceof ReceiveMessageResult) { | ||
afterConsumerResponse(request, response, consumerInstrumenter); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** Create and close CONSUMER span for each message consumed. */ | ||
private static void afterConsumerResponse( | ||
Request<?> request, | ||
Response<?> response, | ||
Instrumenter<Request<?>, Response<?>> consumerInstrumenter) { | ||
ReceiveMessageResult receiveMessageResult = (ReceiveMessageResult) response.getAwsResponse(); | ||
for (Message message : receiveMessageResult.getMessages()) { | ||
createConsumerSpan(message, request, response, consumerInstrumenter); | ||
} | ||
} | ||
|
||
private static void createConsumerSpan( | ||
Message message, | ||
Request<?> request, | ||
Response<?> response, | ||
Instrumenter<Request<?>, Response<?>> consumerInstrumenter) { | ||
Context parentContext = SqsParentContext.ofSystemAttributes(message.getAttributes()); | ||
Context context = consumerInstrumenter.start(parentContext, request); | ||
consumerInstrumenter.end(context, request, response, null); | ||
} | ||
|
||
static boolean beforeMarshalling(AmazonWebServiceRequest rawRequest) { | ||
if (rawRequest instanceof ReceiveMessageRequest) { | ||
ReceiveMessageRequest request = (ReceiveMessageRequest) rawRequest; | ||
if (!request.getAttributeNames().contains(SqsParentContext.AWS_TRACE_SYSTEM_ATTRIBUTE)) { | ||
request.withAttributeNames(SqsParentContext.AWS_TRACE_SYSTEM_ATTRIBUTE); | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
63 changes: 0 additions & 63 deletions
63
...library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/SqsMessageAccess.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.