diff --git a/.fossa.yml b/.fossa.yml
index 69f5797172..7d094439bd 100644
--- a/.fossa.yml
+++ b/.fossa.yml
@@ -346,6 +346,12 @@ targets:
- type: gradle
path: ./
target: ':instrumentation:aws-lambda:aws-lambda-events-2.2:library'
+ - type: gradle
+ path: ./
+ target: ':instrumentation:aws-lambda:aws-lambda-events-3.11:library'
+ - type: gradle
+ path: ./
+ target: ':instrumentation:aws-lambda:aws-lambda-events-common-2.2:library'
- type: gradle
path: ./
target: ':instrumentation:aws-sdk:aws-sdk-1.11:javaagent'
diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md
index cc87ac34c0..a46bc7da28 100644
--- a/docs/supported-libraries.md
+++ b/docs/supported-libraries.md
@@ -47,7 +47,7 @@ These are the supported libraries and frameworks:
| [Armeria gRPC](https://armeria.dev) | 1.14+ | | [RPC Client Spans], [RPC Client Metrics], [RPC Server Spans], [RPC Server Metrics] |
| [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client) | 1.9+ | N/A | [HTTP Client Spans], [HTTP Client Metrics] |
| [Avaje Jex](https://avaje.io/jex/) | 3.0+ | N/A | Provides `http.route` [2] |
-| [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html) | 1.0+ | [opentelemetry-aws-lambda-core-1.0](../instrumentation/aws-lambda/aws-lambda-core-1.0/library),
[opentelemetry-aws-lambda-events-2.2](../instrumentation/aws-lambda/aws-lambda-events-2.2/library) | [FaaS Server Spans] |
+| [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html) | 1.0+ | [opentelemetry-aws-lambda-core-1.0](../instrumentation/aws-lambda/aws-lambda-core-1.0/library),
[opentelemetry-aws-lambda-events-3.11](../instrumentation/aws-lambda/aws-lambda-events-3.11/library) | [FaaS Server Spans] |
| [AWS SDK](https://aws.amazon.com/sdk-for-java/) | 1.11 - 1.12.583,
2.2+ | [opentelemetry-aws-sdk-1.11](../instrumentation/aws-sdk/aws-sdk-1.11/library),
[opentelemetry-aws-sdk-1.11-autoconfigure](../instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure),
[opentelemetry-aws-sdk-2.2](../instrumentation/aws-sdk/aws-sdk-2.2/library),
[opentelemetry-aws-sdk-2.2-autoconfigure](../instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure) | [Messaging Spans], [Database Client Spans], [Database Client Metrics] [6], [HTTP Client Spans], [GenAI Client Spans], [GenAI Client Metrics] |
| [Azure Core](https://docs.microsoft.com/en-us/java/api/overview/azure/core-readme) | 1.14+ | N/A | Context propagation |
| [Cassandra Driver](https://github.com/datastax/java-driver) | 3.0+ | [opentelemetry-cassandra-4.4](../instrumentation/cassandra/cassandra-4.4/library) | [Database Client Spans], [Database Client Metrics] [6] |
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/build.gradle.kts
index acfad8626d..dba82d6f6c 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/build.gradle.kts
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/build.gradle.kts
@@ -17,7 +17,7 @@ dependencies {
implementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
- implementation(project(":instrumentation:aws-lambda:aws-lambda-events-2.2:library")) {
+ implementation(project(":instrumentation:aws-lambda:aws-lambda-events-common-2.2:library")) {
// Only needed by wrappers, not the javaagent. Muzzle will catch if we accidentally change this.
exclude("com.fasterxml.jackson.core", "jackson-databind")
}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaSingletons.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaSingletons.java
index 1ecafdeb19..8ffd8f7a10 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaSingletons.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaSingletons.java
@@ -10,19 +10,21 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrapperConfiguration;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig;
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
import java.time.Duration;
public final class AwsLambdaSingletons {
-
+ private static final String INSTRUMENTATION_NAME = "io.opentelemetry.aws-lambda-events-2.2";
private static final AwsLambdaFunctionInstrumenter FUNCTION_INSTRUMENTER =
AwsLambdaEventsInstrumenterFactory.createInstrumenter(
- GlobalOpenTelemetry.get(), AgentCommonConfig.get().getKnownHttpRequestMethods());
+ GlobalOpenTelemetry.get(),
+ INSTRUMENTATION_NAME,
+ AgentCommonConfig.get().getKnownHttpRequestMethods());
private static final Instrumenter MESSAGE_TRACER =
- AwsLambdaSqsInstrumenterFactory.forEvent(GlobalOpenTelemetry.get());
+ AwsLambdaSqsInstrumenterFactory.forEvent(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME);
private static final Duration FLUSH_TIMEOUT =
Duration.ofMillis(
AgentInstrumentationConfig.get()
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/build.gradle.kts
index baae82471b..b57f150698 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/build.gradle.kts
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/build.gradle.kts
@@ -4,13 +4,12 @@ plugins {
dependencies {
api(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
+ implementation(project(":instrumentation:aws-lambda:aws-lambda-events-common-2.2:library"))
+ compileOnly(project(":instrumentation:aws-lambda:aws-lambda-events-3.11:library"))
compileOnly("io.opentelemetry:opentelemetry-sdk")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
- compileOnly("com.google.auto.value:auto-value-annotations")
- annotationProcessor("com.google.auto.value:auto-value")
-
library("com.amazonaws:aws-lambda-java-core:1.0.0")
// First version to includes support for SQSEvent, currently the most popular message queue used
// with lambda.
@@ -25,13 +24,6 @@ dependencies {
// So that is the reason that why we add it as compile only dependency.
compileOnly("com.amazonaws:aws-lambda-java-serialization:1.1.5")
- // We need Jackson for wrappers to reproduce the serialization does when Lambda invokes a RequestHandler with event
- // since Lambda will only be able to invoke the wrapper itself with a generic Object.
- // Note that Lambda itself uses Jackson, but does not expose it to the function so we need to include it here.
- // TODO: Switch to aws-lambda-java-serialization to more robustly follow Lambda's serialization logic.
- implementation("com.fasterxml.jackson.core:jackson-databind")
- implementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator")
-
// allows to get the function ARN
testLibrary("com.amazonaws:aws-lambda-java-core:1.2.1")
// allows to get the default events
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestApiGatewayWrapper.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestApiGatewayWrapper.java
index 711b7e3079..717cf7d30d 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestApiGatewayWrapper.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestApiGatewayWrapper.java
@@ -9,7 +9,7 @@ import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.SerializationUtil;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.util.function.BiFunction;
@@ -17,7 +17,12 @@ import java.util.function.BiFunction;
* Wrapper for {@link io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler}.
* Allows for wrapping a lambda proxied through API Gateway, enabling single span tracing and HTTP
* context propagation.
+ *
+ * @deprecated use {@link
+ * io.opentelemetry.instrumentation.awslambdaevents.v3_11.TracingRequestApiGatewayWrapper}
+ * instead.
*/
+@Deprecated
public class TracingRequestApiGatewayWrapper
extends TracingRequestWrapperBase {
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapper.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapper.java
index 484ee169d6..a062beea24 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapper.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapper.java
@@ -12,7 +12,8 @@ import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestStreamW
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.ApiGatewayProxyRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.SerializationUtil;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.LambdaParameters;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -26,7 +27,11 @@ import java.util.Map;
/**
* Wrapper for {@link com.amazonaws.services.lambda.runtime.RequestHandler} based Lambda handlers.
+ *
+ * @deprecated use {@link
+ * io.opentelemetry.instrumentation.awslambdaevents.v3_11.TracingRequestWrapper} instead.
*/
+@Deprecated
public class TracingRequestWrapper extends TracingRequestStreamWrapper {
public TracingRequestWrapper() {
super();
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperBase.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperBase.java
index 5169c8f121..239cf07620 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperBase.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperBase.java
@@ -12,7 +12,8 @@ import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrapperConfiguration;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.LambdaParameters;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import java.lang.reflect.InvocationTargetException;
@@ -26,6 +27,7 @@ import java.util.function.BiFunction;
* env property OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER in package.ClassName::methodName format
*/
abstract class TracingRequestWrapperBase extends TracingRequestHandler {
+ private static final String INSTRUMENTATION_NAME = "io.opentelemetry.aws-lambda-events-2.2";
private final WrappedLambda wrappedLambda;
private final Method targetMethod;
@@ -47,7 +49,7 @@ abstract class TracingRequestWrapperBase extends TracingRequestHandler {
+ static final String INSTRUMENTATION_NAME = "io.opentelemetry.aws-lambda-events-2.2";
private final Instrumenter instrumenter;
@@ -33,7 +39,9 @@ public abstract class TracingSqsEventHandler extends TracingRequestHandler messageInstrumenter;
@@ -33,7 +38,9 @@ public abstract class TracingSqsMessageHandler extends TracingSqsEventHandler {
*/
protected TracingSqsMessageHandler(OpenTelemetrySdk openTelemetrySdk, Duration flushTimeout) {
this(
- openTelemetrySdk, flushTimeout, AwsLambdaSqsInstrumenterFactory.forEvent(openTelemetrySdk));
+ openTelemetrySdk,
+ flushTimeout,
+ AwsLambdaSqsInstrumenterFactory.forEvent(openTelemetrySdk, INSTRUMENTATION_NAME));
}
/**
@@ -50,7 +57,7 @@ public abstract class TracingSqsMessageHandler extends TracingSqsEventHandler {
openTelemetrySdk,
flushTimeout,
eventInstrumenter,
- AwsLambdaSqsInstrumenterFactory.forMessage(openTelemetrySdk));
+ AwsLambdaSqsInstrumenterFactory.forMessage(openTelemetrySdk, INSTRUMENTATION_NAME));
}
/**
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaApiGatewayWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaApiGatewayWrapperTest.java
index 4c37d92a5b..f19e3b8488 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaApiGatewayWrapperTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaApiGatewayWrapperTest.java
@@ -36,6 +36,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
+@SuppressWarnings("deprecation") // testing deprecated class
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class AwsLambdaApiGatewayWrapperTest {
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventHandlerTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventHandlerTest.java
index f46fa01eb4..e9486d53f2 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventHandlerTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventHandlerTest.java
@@ -13,6 +13,7 @@ import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExte
import io.opentelemetry.sdk.OpenTelemetrySdk;
import org.junit.jupiter.api.extension.RegisterExtension;
+@SuppressWarnings("deprecation") // testing deprecated class
class AwsLambdaSqsEventHandlerTest extends AbstractAwsLambdaSqsEventHandlerTest {
@RegisterExtension
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventWrapperTest.java
index 18344969fd..54e5e83055 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventWrapperTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsEventWrapperTest.java
@@ -32,6 +32,7 @@ import org.junitpioneer.jupiter.SetEnvironmentVariable;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+@SuppressWarnings("deprecation") // testing deprecated class
@ExtendWith(MockitoExtension.class)
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMessageHandlerTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMessageHandlerTest.java
index 04c6538bbe..13deea3b52 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMessageHandlerTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaSqsMessageHandlerTest.java
@@ -36,6 +36,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+@SuppressWarnings("deprecation") // testing deprecated class
@ExtendWith(MockitoExtension.class)
class AwsLambdaSqsMessageHandlerTest {
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaWrapperTest.java
index f72fe08f5d..d9af41616f 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaWrapperTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AwsLambdaWrapperTest.java
@@ -29,6 +29,7 @@ import org.junitpioneer.jupiter.SetEnvironmentVariable;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+@SuppressWarnings("deprecation") // testing deprecated class
@ExtendWith(MockitoExtension.class)
class AwsLambdaWrapperTest {
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperStandardEventsTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperStandardEventsTest.java
index c25d911ed1..1c9d773668 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperStandardEventsTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/TracingRequestWrapperStandardEventsTest.java
@@ -16,7 +16,7 @@ import com.amazonaws.services.lambda.runtime.events.SNSEvent;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.SerializationUtil;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.io.IOException;
import java.util.HashMap;
@@ -24,6 +24,7 @@ import java.util.Map;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
+@SuppressWarnings("deprecation") // testing deprecated class
class TracingRequestWrapperStandardEventsTest {
private static final Map, EventInfo> EVENTS_JSON = buildEventExamples();
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AbstractAwsLambdaSqsEventHandlerTest.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AbstractAwsLambdaSqsEventHandlerTest.java
index 4ee2278873..7c69c27e38 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AbstractAwsLambdaSqsEventHandlerTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/AbstractAwsLambdaSqsEventHandlerTest.java
@@ -35,7 +35,7 @@ public abstract class AbstractAwsLambdaSqsEventHandlerTest {
private static final String AWS_TRACE_HEADER =
"Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1";
- protected abstract RequestHandler handler();
+ protected abstract RequestHandler handler();
protected abstract InstrumentationExtension testing();
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/README.md b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/README.md
new file mode 100644
index 0000000000..cbde50929e
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/README.md
@@ -0,0 +1,136 @@
+# AWS Lambda Instrumentation
+
+This package contains libraries to help instrument AWS lambda functions in your code.
+
+## Using wrappers
+
+To use the instrumentation, configure `OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER` env property to your lambda handler method in following format `package.ClassName::methodName`
+and use one of wrappers as your lambda `Handler`.
+
+In order to configure a span flush timeout (default is set to 10 seconds), please configure `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` env property. The value is in milliseconds.
+
+Available wrappers:
+
+- `io.opentelemetry.instrumentation.awslambdaevents.v3_11.TracingRequestWrapper` - for wrapping regular handlers (implementing `RequestHandler`)
+- `io.opentelemetry.instrumentation.awslambdaevents.v3_11.TracingRequestApiGatewayWrapper` - for wrapping regular handlers (implementing `RequestHandler`) proxied through API Gateway, enabling HTTP context propagation
+- `io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestStreamWrapper` - for wrapping streaming handlers (implementing `RequestStreamHandler`), enabling HTTP context propagation for HTTP requests
+
+If you are only using `TracingRequestStreamWrapper`, consider using [aws-lambda-core-1.0](../../aws-lambda-core-1.0/library) instead to reduce the size of
+your compiled function.
+
+## Using handlers
+
+To use the instrumentation, replace your function classes that implement `RequestHandler` (or `RequestStreamHandler`) with those
+that extend `TracingRequestHandler` (or `TracingRequestStreamHandler`). You will need to change the method name to `doHandleRequest`
+and pass an initialized `OpenTelemetrySdk` to the base class.
+
+```java
+public class MyRequestHandler extends TracingRequestHandler {
+
+ private static final OpenTelemetrySdk SDK = OpenTelemetrySdk.builder()
+ .addSpanProcessor(spanProcessor)
+ .buildAndRegisterGlobal();
+
+ public MyRequestHandler() {
+ super(SDK);
+ }
+
+ // Note the method is named doHandleRequest instead of handleRequest.
+ @Override
+ protected String doHandleRequest(String input, Context context) {
+ if (input.equals("hello")) {
+ return "world";
+ }
+ return "goodbye";
+ }
+}
+```
+
+A `SERVER` span will be created with the name you specify for the function when deploying it.
+
+In addition, it is recommended to set up X-Ray trace propagation to be able to
+link to tracing information provided by Lambda itself. To do so, add a dependency on
+`opentelemetry-extension-tracepropagators`. Make sure the version matches the version of the SDK
+you use.
+
+Gradle:
+
+```kotlin
+dependencies {
+ implementation("io.opentelemetry:opentelemetry-extension-trace-propagators:0.8.0")
+}
+```
+
+Maven:
+
+```xml
+
+
+ io.opentelemetry
+ opentelemetry-extension-trace-propagators
+ 0.8.0
+
+
+```
+
+## SQS Handler
+
+This package provides a special handler for SQS-triggered functions to include messaging data.
+If using SQS, it is recommended to use them instead of `TracingRequestHandler`.
+
+If your application processes one message at a time, each independently, it is recommended to extend
+`TracingSQSMessageHandler`. This will create a single span corresponding to a received batch of
+messages along with one span for each of the messages as you process them.
+
+```java
+public class MyMessageHandler extends TracingSQSMessageHandler {
+ @Override
+ protected boolean handleMessage(SQSMessage message, Context context) {
+ System.out.println(message.getBody());
+ return true;
+ }
+}
+```
+
+If you handle a batch of messages together, for example by aggregating them into a single unit,
+extend `TracingSQSEventHandler` to process a batch at a time.
+
+```java
+public class MyBatchHandler extends TracingSQSEventHandler {
+ @Override
+ protected SQSBatchResponse handleEvent(SQSEvent event, Context context) {
+ System.out.println(event.getRecords().size());
+ return null;
+ }
+}
+```
+
+## Trace propagation
+
+Context propagation for this instrumentation can be done either with X-Ray propagation or regular HTTP propagation. If X-Ray is enabled for instrumented lambda, it will be preferred. If X-Ray is disabled, HTTP propagation will be tried (that is HTTP headers will be read to check for a valid trace context).
+
+### X-Ray propagation
+
+This instrumentation supports propagating traces using the `X-Amzn-Trace-Id` format for both normal
+requests and SQS requests. X-Ray propagation is always enabled, there is no need to configure it explicitly.
+
+### HTTP headers based propagation
+
+For API Gateway (HTTP) requests instrumented by using one of following methods:
+
+- extending `TracingRequestStreamHandler` or `TracingRequestHandler`
+- wrapping with `TracingRequestStreamWrapper` or `TracingRequestApiGatewayWrapper`
+ traces can be propagated with supported HTTP headers (see ).
+
+In order to enable requested propagation for a handler, configure it on the SDK you build.
+
+```java
+ static {
+ OpenTelemetrySdk.builder()
+ ...
+ .setPropagators(ContextPropagators.create(B3Propagator.injectingSingleHeader()))
+ .buildAndRegisterGlobal();
+ }
+```
+
+If using the wrappers, set the `OTEL_PROPAGATORS` environment variable as described [here](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#propagator).
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/build.gradle.kts
new file mode 100644
index 0000000000..7e63bb6e53
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/build.gradle.kts
@@ -0,0 +1,30 @@
+plugins {
+ id("otel.library-instrumentation")
+}
+
+dependencies {
+ implementation(project(":instrumentation:aws-lambda:aws-lambda-events-common-2.2:library"))
+
+ compileOnly("io.opentelemetry:opentelemetry-sdk")
+ compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
+
+ library("com.amazonaws:aws-lambda-java-core:1.0.0")
+ library("com.amazonaws:aws-lambda-java-events:3.11.0")
+
+ // allows to get the function ARN
+ testLibrary("com.amazonaws:aws-lambda-java-core:1.2.1")
+
+ testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
+ testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
+ testImplementation("com.amazonaws:aws-lambda-java-serialization:1.1.5")
+
+ testImplementation(project(":instrumentation:aws-lambda:aws-lambda-events-2.2:testing"))
+ testImplementation("uk.org.webcompere:system-stubs-jupiter")
+}
+
+tasks.withType().configureEach {
+ // required on jdk17
+ jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
+ jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED")
+ jvmArgs("-XX:+IgnoreUnrecognizedVMOptions")
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestApiGatewayWrapper.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestApiGatewayWrapper.java
new file mode 100644
index 0000000000..717458b082
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestApiGatewayWrapper.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import java.util.function.BiFunction;
+
+/**
+ * Wrapper for {@link io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler}.
+ * Allows for wrapping a lambda proxied through API Gateway, enabling single span tracing and HTTP
+ * context propagation.
+ */
+public class TracingRequestApiGatewayWrapper
+ extends TracingRequestWrapperBase {
+
+ public TracingRequestApiGatewayWrapper() {
+ super(TracingRequestApiGatewayWrapper::map);
+ }
+
+ // Visible for testing
+ TracingRequestApiGatewayWrapper(
+ OpenTelemetrySdk openTelemetrySdk,
+ WrappedLambda wrappedLambda,
+ BiFunction, Object> mapper) {
+ super(openTelemetrySdk, wrappedLambda, mapper);
+ }
+
+ // Visible for testing
+ static T map(APIGatewayProxyRequestEvent event, Class clazz) {
+ return SerializationUtil.fromJson(event.getBody(), clazz);
+ }
+
+ @Override
+ protected APIGatewayProxyResponseEvent doHandleRequest(
+ APIGatewayProxyRequestEvent input, Context context) {
+ Object result = super.doHandleRequest(input, context);
+ APIGatewayProxyResponseEvent event;
+ // map to response event if needed
+ if (result instanceof APIGatewayProxyResponseEvent) {
+ event = (APIGatewayProxyResponseEvent) result;
+ } else {
+ event = new APIGatewayProxyResponseEvent();
+ event.setBody(SerializationUtil.toJson(result));
+ }
+ return event;
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapper.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapper.java
new file mode 100644
index 0000000000..c3627ea65a
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapper.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestStreamWrapper;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.ApiGatewayProxyRequest;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.LambdaParameters;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Wrapper for {@link com.amazonaws.services.lambda.runtime.RequestHandler} based Lambda handlers.
+ */
+public class TracingRequestWrapper extends TracingRequestStreamWrapper {
+ public TracingRequestWrapper() {
+ super();
+ }
+
+ // Visible for testing
+ TracingRequestWrapper(OpenTelemetrySdk openTelemetrySdk, WrappedLambda wrappedLambda) {
+ super(openTelemetrySdk, wrappedLambda);
+ }
+
+ @Override
+ protected final AwsLambdaRequest createRequest(
+ InputStream inputStream, Context context, ApiGatewayProxyRequest proxyRequest) {
+ Method targetMethod = wrappedLambda.getRequestTargetMethod();
+ Object input = LambdaParameters.toInput(targetMethod, inputStream, TracingRequestWrapper::map);
+ return AwsLambdaRequest.create(context, input, extractHeaders(input));
+ }
+
+ protected Map extractHeaders(Object input) {
+ if (input instanceof APIGatewayProxyRequestEvent) {
+ return MapUtils.emptyIfNull(((APIGatewayProxyRequestEvent) input).getHeaders());
+ }
+ return Collections.emptyMap();
+ }
+
+ @Override
+ protected final void doHandleRequest(
+ InputStream input, OutputStream output, Context context, AwsLambdaRequest request) {
+ Method targetMethod = wrappedLambda.getRequestTargetMethod();
+ Object[] parameters = LambdaParameters.toParameters(targetMethod, request.getInput(), context);
+ try {
+ Object result = targetMethod.invoke(wrappedLambda.getTargetObject(), parameters);
+ SerializationUtil.toJson(output, result);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Method is inaccessible", e);
+ } catch (InvocationTargetException e) {
+ throw (e.getCause() instanceof RuntimeException
+ ? (RuntimeException) e.getCause()
+ : new IllegalStateException(e.getTargetException()));
+ }
+ }
+
+ @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
+ // Used for testing
+ OUTPUT handleRequest(INPUT input, Context context) throws IOException {
+ byte[] inputJsonData = SerializationUtil.toJsonData(input);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(inputJsonData);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ super.handleRequest(inputStream, outputStream, context);
+
+ byte[] outputJsonData = outputStream.toByteArray();
+ return (OUTPUT)
+ SerializationUtil.fromJson(
+ new ByteArrayInputStream(outputJsonData),
+ wrappedLambda.getRequestTargetMethod().getReturnType());
+ }
+
+ // Visible for testing
+ static T map(InputStream inputStream, Class clazz) {
+ try {
+ return SerializationUtil.fromJson(inputStream, clazz);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalStateException(
+ "Could not map input to requested parameter type: " + clazz, e);
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperBase.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperBase.java
new file mode 100644
index 0000000000..df6e6a6504
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperBase.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import io.opentelemetry.instrumentation.api.internal.HttpConstants;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrapperConfiguration;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.LambdaParameters;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.BiFunction;
+
+/**
+ * Base abstract wrapper for {@link TracingRequestHandler}. Provides: - delegation to a lambda via
+ * env property OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER in package.ClassName::methodName format
+ */
+abstract class TracingRequestWrapperBase extends TracingRequestHandler {
+ private static final String INSTRUMENTATION_NAME = "io.opentelemetry.aws-lambda-events-3.11";
+
+ private final WrappedLambda wrappedLambda;
+ private final Method targetMethod;
+ private final BiFunction, Object> parameterMapper;
+
+ protected TracingRequestWrapperBase(BiFunction, Object> parameterMapper) {
+ this(
+ AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ parameterMapper);
+ }
+
+ // Visible for testing
+ TracingRequestWrapperBase(
+ OpenTelemetrySdk openTelemetrySdk,
+ WrappedLambda wrappedLambda,
+ BiFunction, Object> parameterMapper) {
+ super(
+ openTelemetrySdk,
+ WrapperConfiguration.flushTimeout(),
+ AwsLambdaEventsInstrumenterFactory.createInstrumenter(
+ openTelemetrySdk, INSTRUMENTATION_NAME, HttpConstants.KNOWN_METHODS));
+ this.wrappedLambda = wrappedLambda;
+ this.targetMethod = wrappedLambda.getRequestTargetMethod();
+ this.parameterMapper = parameterMapper;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected O doHandleRequest(I input, Context context) {
+ Object[] parameters = LambdaParameters.toArray(targetMethod, input, context, parameterMapper);
+ O result;
+ try {
+ result = (O) targetMethod.invoke(wrappedLambda.getTargetObject(), parameters);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Method is inaccessible", e);
+ } catch (InvocationTargetException e) {
+ throw (e.getCause() instanceof RuntimeException
+ ? (RuntimeException) e.getCause()
+ : new IllegalStateException(e.getTargetException()));
+ }
+ return result;
+ }
+
+ @Override
+ protected final Map extractHttpHeaders(I input) {
+ if (input instanceof APIGatewayProxyRequestEvent) {
+ return MapUtils.emptyIfNull(((APIGatewayProxyRequestEvent) input).getHeaders());
+ }
+ return Collections.emptyMap();
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventHandler.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventHandler.java
new file mode 100644
index 0000000000..b0e7727eec
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventHandler.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import io.opentelemetry.context.Scope;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import java.time.Duration;
+import javax.annotation.Nullable;
+
+public abstract class TracingSqsEventHandler
+ extends TracingRequestHandler {
+ static final String INSTRUMENTATION_NAME = "io.opentelemetry.aws-lambda-events-3.11";
+
+ private final Instrumenter instrumenter;
+
+ /**
+ * Creates a new {@link TracingSqsEventHandler} which traces using the provided {@link
+ * OpenTelemetrySdk} and has a timeout of 1s when flushing at the end of an invocation.
+ */
+ protected TracingSqsEventHandler(OpenTelemetrySdk openTelemetrySdk) {
+ this(openTelemetrySdk, DEFAULT_FLUSH_TIMEOUT);
+ }
+
+ /**
+ * Creates a new {@link TracingSqsEventHandler} which traces using the provided {@link
+ * OpenTelemetrySdk} and has a timeout of {@code flushTimeout} when flushing at the end of an
+ * invocation.
+ */
+ protected TracingSqsEventHandler(OpenTelemetrySdk openTelemetrySdk, Duration flushTimeout) {
+ this(
+ openTelemetrySdk,
+ flushTimeout,
+ AwsLambdaSqsInstrumenterFactory.forEvent(openTelemetrySdk, INSTRUMENTATION_NAME));
+ }
+
+ /**
+ * Creates a new {@link TracingSqsEventHandler} which flushes the provided {@link
+ * OpenTelemetrySdk}, has a timeout of {@code flushTimeout} when flushing at the end of an
+ * invocation, and traces using the provided {@link
+ * io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter}.
+ */
+ protected TracingSqsEventHandler(
+ OpenTelemetrySdk openTelemetrySdk,
+ Duration flushTimeout,
+ Instrumenter instrumenter) {
+ super(openTelemetrySdk, flushTimeout);
+ this.instrumenter = instrumenter;
+ }
+
+ @Nullable
+ @Override
+ public SQSBatchResponse doHandleRequest(SQSEvent event, Context context) {
+ io.opentelemetry.context.Context parentContext = io.opentelemetry.context.Context.current();
+ if (instrumenter.shouldStart(parentContext, event)) {
+ io.opentelemetry.context.Context otelContext = instrumenter.start(parentContext, event);
+ Throwable error = null;
+ try (Scope ignored = otelContext.makeCurrent()) {
+ return handleEvent(event, context);
+ } catch (Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ instrumenter.end(otelContext, event, null, error);
+ }
+ } else {
+ return handleEvent(event, context);
+ }
+ }
+
+ /**
+ * Handles a {@linkplain SQSEvent batch of messages}. Implement this class to do the actual
+ * processing of incoming SQS messages.
+ */
+ @Nullable
+ protected abstract SQSBatchResponse handleEvent(SQSEvent event, Context context);
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventWrapper.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventWrapper.java
new file mode 100644
index 0000000000..7163d37473
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsEventWrapper.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrapperConfiguration;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.LambdaParameters;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class TracingSqsEventWrapper extends TracingSqsEventHandler {
+
+ private final WrappedLambda wrappedLambda;
+ private final Method targetMethod;
+
+ public TracingSqsEventWrapper() {
+ this(
+ AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration());
+ }
+
+ // Visible for testing
+ TracingSqsEventWrapper(OpenTelemetrySdk openTelemetrySdk, WrappedLambda wrappedLambda) {
+ super(openTelemetrySdk, WrapperConfiguration.flushTimeout());
+ this.wrappedLambda = wrappedLambda;
+ this.targetMethod = wrappedLambda.getRequestTargetMethod();
+ }
+
+ @Override
+ protected SQSBatchResponse handleEvent(SQSEvent sqsEvent, Context context) {
+ Object[] parameters =
+ LambdaParameters.toArray(targetMethod, sqsEvent, context, (event, clazz) -> event);
+ try {
+ Object result = targetMethod.invoke(wrappedLambda.getTargetObject(), parameters);
+ return result instanceof SQSBatchResponse ? (SQSBatchResponse) result : null;
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Method is inaccessible", e);
+ } catch (InvocationTargetException e) {
+ throw (e.getCause() instanceof RuntimeException
+ ? (RuntimeException) e.getCause()
+ : new IllegalStateException(e.getTargetException()));
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsMessageHandler.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsMessageHandler.java
new file mode 100644
index 0000000000..d6d315a46d
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingSqsMessageHandler.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
+import io.opentelemetry.context.Scope;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class TracingSqsMessageHandler extends TracingSqsEventHandler {
+
+ private final Instrumenter messageInstrumenter;
+
+ /**
+ * Creates a new {@link TracingSqsMessageHandler} which traces using the provided {@link
+ * OpenTelemetrySdk} and has a timeout of 1s when flushing at the end of an invocation.
+ */
+ protected TracingSqsMessageHandler(OpenTelemetrySdk openTelemetrySdk) {
+ this(openTelemetrySdk, DEFAULT_FLUSH_TIMEOUT);
+ }
+
+ /**
+ * Creates a new {@link TracingSqsMessageHandler} which traces using the provided {@link
+ * OpenTelemetrySdk} and has a timeout of {@code flushTimeout} when flushing at the end of an
+ * invocation.
+ */
+ protected TracingSqsMessageHandler(OpenTelemetrySdk openTelemetrySdk, Duration flushTimeout) {
+ this(
+ openTelemetrySdk,
+ flushTimeout,
+ AwsLambdaSqsInstrumenterFactory.forEvent(openTelemetrySdk, INSTRUMENTATION_NAME));
+ }
+
+ /**
+ * Creates a new {@link TracingSqsMessageHandler} which flushes the provided {@link
+ * OpenTelemetrySdk}, has a timeout of {@code flushTimeout} when flushing at the end of an
+ * invocation, and instruments {@link SQSEvent} using the provided {@code Instrumenter}.
+ */
+ protected TracingSqsMessageHandler(
+ OpenTelemetrySdk openTelemetrySdk,
+ Duration flushTimeout,
+ Instrumenter eventInstrumenter) {
+ this(
+ openTelemetrySdk,
+ flushTimeout,
+ eventInstrumenter,
+ AwsLambdaSqsInstrumenterFactory.forMessage(openTelemetrySdk, INSTRUMENTATION_NAME));
+ }
+
+ /**
+ * Creates a new {@link TracingSqsMessageHandler} which flushes the provided {@link
+ * OpenTelemetrySdk}, has a timeout of {@code flushTimeout} when flushing at the end of an
+ * invocation, and traces using the provided {@code Instrumenter} and {@code
+ * Instrumenter}.
+ */
+ protected TracingSqsMessageHandler(
+ OpenTelemetrySdk openTelemetrySdk,
+ Duration flushTimeout,
+ Instrumenter eventInstrumenter,
+ Instrumenter messageInstrumenter) {
+ super(openTelemetrySdk, flushTimeout, eventInstrumenter);
+ this.messageInstrumenter = messageInstrumenter;
+ }
+
+ @Override
+ protected final SQSBatchResponse handleEvent(SQSEvent event, Context context) {
+ List batchItemFailures = new ArrayList<>();
+ io.opentelemetry.context.Context parentContext = io.opentelemetry.context.Context.current();
+ for (SQSMessage message : event.getRecords()) {
+ if (messageInstrumenter.shouldStart(parentContext, message)) {
+ io.opentelemetry.context.Context otelContext =
+ messageInstrumenter.start(parentContext, message);
+ Throwable error = null;
+ try (Scope ignored = otelContext.makeCurrent()) {
+ handleMessage(message, context, batchItemFailures);
+ } catch (Throwable t) {
+ error = t;
+ throw t;
+ } finally {
+ messageInstrumenter.end(otelContext, message, null, error);
+ }
+ } else {
+ handleMessage(message, context, batchItemFailures);
+ }
+ }
+
+ return new SQSBatchResponse(batchItemFailures);
+ }
+
+ private void handleMessage(
+ SQSMessage message,
+ Context context,
+ List batchItemFailures) {
+ if (!handleMessage(message, context)) {
+ batchItemFailures.add(new SQSBatchResponse.BatchItemFailure(message.getMessageId()));
+ }
+ }
+
+ /**
+ * Handles a {@linkplain SQSMessage message}. Implement this class to do the actual processing of
+ * incoming SQS messages.
+ *
+ * @return {@code true} when message was processed successfully, {@code false} when it should be
+ * reported as a failed batch item.
+ */
+ protected abstract boolean handleMessage(SQSMessage message, Context context);
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaApiGatewayWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaApiGatewayWrapperTest.java
new file mode 100644
index 0000000000..d0bf6a93e5
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaApiGatewayWrapperTest.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
+import static io.opentelemetry.semconv.HttpAttributes.HTTP_REQUEST_METHOD;
+import static io.opentelemetry.semconv.HttpAttributes.HTTP_RESPONSE_STATUS_CODE;
+import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
+import static io.opentelemetry.semconv.UserAgentAttributes.USER_AGENT_ORIGINAL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
+import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
+import io.opentelemetry.semconv.incubating.FaasIncubatingAttributes;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junitpioneer.jupiter.SetEnvironmentVariable;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class AwsLambdaApiGatewayWrapperTest {
+
+ @RegisterExtension
+ static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
+
+ @Mock private Context context;
+
+ @BeforeEach
+ void setUp() {
+ when(context.getFunctionName()).thenReturn("my_function");
+ when(context.getAwsRequestId()).thenReturn("1-22-333");
+ when(context.getInvokedFunctionArn())
+ .thenReturn("arn:aws:lambda:us-east-1:123456789:function:test");
+ }
+
+ @AfterEach
+ void tearDown() {
+ assertThat(testing.forceFlushCalled()).isTrue();
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
+ void tracedWithHttpPropagation() {
+ TracingRequestApiGatewayWrapper wrapper =
+ new TracingRequestApiGatewayWrapper(
+ testing.getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ TracingRequestApiGatewayWrapper::map);
+
+ Map headers = new HashMap<>();
+ headers.put("traceparent", "00-4fd0b6131f19f39af59518d127b0cafe-0000000000000456-01");
+ headers.put("User-Agent", "Test Client");
+ headers.put("host", "localhost:123");
+ headers.put("X-FORWARDED-PROTO", "http");
+ Map query = new HashMap<>();
+ query.put("a", "b");
+ query.put("c", "d");
+ APIGatewayProxyRequestEvent input =
+ new APIGatewayProxyRequestEvent()
+ .withHttpMethod("GET")
+ .withResource("/hello/{param}")
+ .withPath("/hello/world")
+ .withBody("hello")
+ .withQueryStringParameters(query)
+ .withHeaders(headers);
+
+ APIGatewayProxyResponseEvent result =
+ (APIGatewayProxyResponseEvent) wrapper.handleRequest(input, context);
+
+ assertThat(result.getBody()).isEqualTo("world");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("GET /hello/{param}")
+ .hasKind(SpanKind.SERVER)
+ .hasTraceId("4fd0b6131f19f39af59518d127b0cafe")
+ .hasParentSpanId("0000000000000456")
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"),
+ equalTo(FaasIncubatingAttributes.FAAS_TRIGGER, "http"),
+ equalTo(HTTP_REQUEST_METHOD, "GET"),
+ equalTo(USER_AGENT_ORIGINAL, "Test Client"),
+ equalTo(URL_FULL, "http://localhost:123/hello/world?a=b&c=d"),
+ equalTo(HTTP_RESPONSE_STATUS_CODE, 200L))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
+ void handlerTraced_empty() {
+ TracingRequestApiGatewayWrapper wrapper =
+ new TracingRequestApiGatewayWrapper(
+ testing.getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ TracingRequestApiGatewayWrapper::map);
+ APIGatewayProxyResponseEvent result =
+ (APIGatewayProxyResponseEvent)
+ wrapper.handleRequest(new APIGatewayProxyRequestEvent().withBody("empty"), context);
+
+ assertThat(result.getBody()).isNull();
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"),
+ equalTo(FaasIncubatingAttributes.FAAS_TRIGGER, "http"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerString::handleRequest")
+ void handlerTraced_string() {
+ TracingRequestApiGatewayWrapper wrapper =
+ new TracingRequestApiGatewayWrapper(
+ testing.getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ TracingRequestApiGatewayWrapper::map);
+ APIGatewayProxyResponseEvent result =
+ (APIGatewayProxyResponseEvent)
+ wrapper.handleRequest(new APIGatewayProxyRequestEvent().withBody("\"hello\""), context);
+
+ assertThat(result.getBody()).isEqualTo("\"world\"");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"),
+ equalTo(FaasIncubatingAttributes.FAAS_TRIGGER, "http"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerInteger::handleRequest")
+ void handlerTraced_integer() {
+ TracingRequestApiGatewayWrapper wrapper =
+ new TracingRequestApiGatewayWrapper(
+ testing.getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ TracingRequestApiGatewayWrapper::map);
+ APIGatewayProxyResponseEvent result =
+ (APIGatewayProxyResponseEvent)
+ wrapper.handleRequest(new APIGatewayProxyRequestEvent().withBody("1"), context);
+
+ assertThat(result.getBody()).isEqualTo("\"world\"");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"),
+ equalTo(FaasIncubatingAttributes.FAAS_TRIGGER, "http"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerCustomType::handleRequest")
+ void handlerTraced_customType() {
+ TracingRequestApiGatewayWrapper wrapper =
+ new TracingRequestApiGatewayWrapper(
+ testing.getOpenTelemetrySdk(),
+ WrappedLambda.fromConfiguration(),
+ TracingRequestApiGatewayWrapper::map);
+ APIGatewayProxyResponseEvent result =
+ (APIGatewayProxyResponseEvent)
+ wrapper.handleRequest(
+ new APIGatewayProxyRequestEvent()
+ .withBody("{\"key\":\"hello\", \"value\":\"General Kenobi\"}"),
+ context);
+
+ assertThat(result.getBody()).isEqualTo("\"General Kenobi\"");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"),
+ equalTo(FaasIncubatingAttributes.FAAS_TRIGGER, "http"))));
+ }
+
+ public static class TestRequestHandlerApiGateway
+ implements RequestHandler {
+
+ @Override
+ public APIGatewayProxyResponseEvent handleRequest(
+ APIGatewayProxyRequestEvent input, Context context) {
+ if (input.getBody().equals("hello")) {
+ return new APIGatewayProxyResponseEvent().withStatusCode(200).withBody("world");
+ } else if (input.getBody().equals("empty")) {
+ return new APIGatewayProxyResponseEvent();
+ }
+ throw new IllegalStateException("bad request");
+ }
+ }
+
+ public static final class TestRequestHandlerString implements RequestHandler {
+
+ @Override
+ public String handleRequest(String input, Context context) {
+ if (input.equals("hello")) {
+ return "world";
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+
+ public static final class TestRequestHandlerInteger implements RequestHandler {
+
+ @Override
+ public String handleRequest(Integer input, Context context) {
+ if (input == 1) {
+ return "world";
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+
+ public static class CustomType {
+ public String key;
+ public String value;
+ }
+
+ public static final class TestRequestHandlerCustomType
+ implements RequestHandler {
+
+ @Override
+ public String handleRequest(CustomType input, Context context) {
+ if (input.key.equals("hello")) {
+ return input.value;
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventHandlerTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventHandlerTest.java
new file mode 100644
index 0000000000..50efefcd4a
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventHandlerTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import io.opentelemetry.instrumentation.awslambdaevents.v2_2.AbstractAwsLambdaSqsEventHandlerTest;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+class AwsLambdaSqsEventHandlerTest extends AbstractAwsLambdaSqsEventHandlerTest {
+
+ @RegisterExtension
+ static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
+
+ @Override
+ protected RequestHandler handler() {
+ return new TestHandler(testing.getOpenTelemetrySdk());
+ }
+
+ @Override
+ protected InstrumentationExtension testing() {
+ return testing;
+ }
+
+ private static final class TestHandler extends TracingSqsEventHandler {
+
+ TestHandler(OpenTelemetrySdk openTelemetrySdk) {
+ super(openTelemetrySdk);
+ }
+
+ @Override
+ protected SQSBatchResponse handleEvent(SQSEvent event, Context context) {
+ return null;
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventWrapperTest.java
new file mode 100644
index 0000000000..e2216828bf
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsEventWrapperTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
+import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
+import io.opentelemetry.semconv.incubating.FaasIncubatingAttributes;
+import io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes;
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junitpioneer.jupiter.SetEnvironmentVariable;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+@SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaSqsEventWrapperTest$TestRequestHandler::handleRequest")
+class AwsLambdaSqsEventWrapperTest {
+
+ @RegisterExtension
+ static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
+
+ @Mock private Context context;
+
+ @BeforeEach
+ void setUp() {
+ when(context.getFunctionName()).thenReturn("my_function");
+ when(context.getAwsRequestId()).thenReturn("1-22-333");
+ when(context.getInvokedFunctionArn())
+ .thenReturn("arn:aws:lambda:us-east-1:123456789:function:test");
+ }
+
+ @AfterEach
+ void tearDown() {
+ assertThat(testing.forceFlushCalled()).isTrue();
+ }
+
+ @SuppressWarnings("deprecation") // using deprecated semconv
+ @Test
+ void eventTraced() {
+ SQSEvent event = new SQSEvent();
+ SQSEvent.SQSMessage record = newMessage();
+ record.setEventSource("otel");
+ record.setAttributes(Collections.emptyMap());
+ event.setRecords(Collections.singletonList(record));
+
+ TracingSqsEventWrapper wrapper =
+ new TracingSqsEventWrapper(
+ testing.getOpenTelemetrySdk(), WrappedLambda.fromConfiguration());
+ wrapper.handleRequest(event, context);
+
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333")),
+ span ->
+ span.hasName("otel process")
+ .hasKind(SpanKind.CONSUMER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ MESSAGING_SYSTEM,
+ MessagingIncubatingAttributes.MessagingSystemIncubatingValues
+ .AWS_SQS),
+ equalTo(MESSAGING_OPERATION, "process"))));
+ }
+
+ public static final class TestRequestHandler
+ implements RequestHandler {
+ @Override
+ public SQSBatchResponse handleRequest(SQSEvent input, Context context) {
+ return null;
+ }
+ }
+
+ // Constructor private in early versions.
+ private static SQSEvent.SQSMessage newMessage() {
+ try {
+ Constructor ctor = SQSEvent.SQSMessage.class.getDeclaredConstructor();
+ return ctor.newInstance();
+ } catch (Throwable t) {
+ throw new AssertionError(t);
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsMessageHandlerTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsMessageHandlerTest.java
new file mode 100644
index 0000000000..26863fbf08
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaSqsMessageHandlerTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
+import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_SYSTEM;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import io.opentelemetry.api.trace.SpanContext;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.TraceFlags;
+import io.opentelemetry.api.trace.TraceState;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.trace.data.LinkData;
+import io.opentelemetry.semconv.incubating.FaasIncubatingAttributes;
+import io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class AwsLambdaSqsMessageHandlerTest {
+
+ private static final String AWS_TRACE_HEADER1 =
+ "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1";
+ private static final String AWS_TRACE_HEADER2 =
+ "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad9;Sampled=1";
+
+ @RegisterExtension
+ static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
+
+ @Mock private Context context;
+
+ @BeforeEach
+ void setUp() {
+ when(context.getFunctionName()).thenReturn("my_function");
+ when(context.getAwsRequestId()).thenReturn("1-22-333");
+ }
+
+ @AfterEach
+ void tearDown() {
+ assertThat(testing.forceFlushCalled()).isTrue();
+ }
+
+ @SuppressWarnings("deprecation") // using deprecated semconv
+ @Test
+ void processSpans() {
+ SQSEvent.SQSMessage message1 = newMessage();
+ message1.setAttributes(Collections.singletonMap("AWSTraceHeader", AWS_TRACE_HEADER1));
+ message1.setMessageId("message1");
+ message1.setEventSource("queue1");
+
+ SQSEvent.SQSMessage message2 = newMessage();
+ message2.setAttributes(Collections.singletonMap("AWSTraceHeader", AWS_TRACE_HEADER2));
+ message2.setMessageId("message2");
+ message2.setEventSource("queue1");
+
+ SQSEvent event = new SQSEvent();
+ event.setRecords(Arrays.asList(message1, message2));
+
+ SQSBatchResponse response =
+ new TestHandler(testing.getOpenTelemetrySdk()).handleRequest(event, context);
+ assertThat(response.getBatchItemFailures())
+ .satisfiesExactly(item -> assertThat(item.getItemIdentifier()).isEqualTo("message2"));
+
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333")),
+ span ->
+ span.hasName("queue1 process")
+ .hasKind(SpanKind.CONSUMER)
+ .hasParentSpanId(trace.getSpan(0).getSpanId())
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ MESSAGING_SYSTEM,
+ MessagingIncubatingAttributes.MessagingSystemIncubatingValues
+ .AWS_SQS),
+ equalTo(MESSAGING_OPERATION, "process"))
+ .hasLinks(
+ LinkData.create(
+ SpanContext.createFromRemoteParent(
+ "5759e988bd862e3fe1be46a994272793",
+ "53995c3f42cd8ad8",
+ TraceFlags.getSampled(),
+ TraceState.getDefault())),
+ LinkData.create(
+ SpanContext.createFromRemoteParent(
+ "5759e988bd862e3fe1be46a994272793",
+ "53995c3f42cd8ad9",
+ TraceFlags.getSampled(),
+ TraceState.getDefault()))),
+ span ->
+ span.hasName("queue1 process")
+ .hasKind(SpanKind.CONSUMER)
+ .hasParentSpanId(trace.getSpan(1).getSpanId())
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ MESSAGING_SYSTEM,
+ MessagingIncubatingAttributes.MessagingSystemIncubatingValues
+ .AWS_SQS),
+ equalTo(MESSAGING_OPERATION, "process"),
+ equalTo(MESSAGING_MESSAGE_ID, "message1"),
+ equalTo(MESSAGING_DESTINATION_NAME, "queue1"))
+ .hasLinks(
+ LinkData.create(
+ SpanContext.createFromRemoteParent(
+ "5759e988bd862e3fe1be46a994272793",
+ "53995c3f42cd8ad8",
+ TraceFlags.getSampled(),
+ TraceState.getDefault()))),
+ span ->
+ span.hasName("queue1 process")
+ .hasKind(SpanKind.CONSUMER)
+ .hasParentSpanId(trace.getSpan(1).getSpanId())
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ MESSAGING_SYSTEM,
+ MessagingIncubatingAttributes.MessagingSystemIncubatingValues
+ .AWS_SQS),
+ equalTo(MESSAGING_OPERATION, "process"),
+ equalTo(MESSAGING_MESSAGE_ID, "message2"),
+ equalTo(MESSAGING_DESTINATION_NAME, "queue1"))
+ .hasLinks(
+ LinkData.create(
+ SpanContext.createFromRemoteParent(
+ "5759e988bd862e3fe1be46a994272793",
+ "53995c3f42cd8ad9",
+ TraceFlags.getSampled(),
+ TraceState.getDefault())))));
+ }
+
+ // Constructor private in early versions.
+ private static SQSEvent.SQSMessage newMessage() {
+ try {
+ Constructor ctor = SQSEvent.SQSMessage.class.getDeclaredConstructor();
+ return ctor.newInstance();
+ } catch (Throwable t) {
+ throw new AssertionError(t);
+ }
+ }
+
+ private static final class TestHandler extends TracingSqsMessageHandler {
+
+ TestHandler(OpenTelemetrySdk openTelemetrySdk) {
+ super(openTelemetrySdk);
+ }
+
+ @Override
+ protected boolean handleMessage(SQSEvent.SQSMessage message, Context context) {
+ return "message1".equals(message.getMessageId());
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaWrapperTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaWrapperTest.java
new file mode 100644
index 0000000000..ad32986d44
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/AwsLambdaWrapperTest.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.mockito.Mockito.when;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
+import io.opentelemetry.sdk.trace.data.StatusData;
+import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;
+import io.opentelemetry.semconv.incubating.FaasIncubatingAttributes;
+import java.io.IOException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junitpioneer.jupiter.SetEnvironmentVariable;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class AwsLambdaWrapperTest {
+
+ @RegisterExtension
+ static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
+
+ @Mock private Context context;
+
+ @BeforeEach
+ void setUp() {
+ when(context.getFunctionName()).thenReturn("my_function");
+ when(context.getAwsRequestId()).thenReturn("1-22-333");
+ when(context.getInvokedFunctionArn())
+ .thenReturn("arn:aws:lambda:us-east-1:123456789:function:test");
+ }
+
+ @AfterEach
+ void tearDown() {
+ assertThat(testing.forceFlushCalled()).isTrue();
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
+ void handlerTraced() throws IOException {
+ TracingRequestWrapper wrapper =
+ new TracingRequestWrapper(testing.getOpenTelemetrySdk(), WrappedLambda.fromConfiguration());
+ Object result = wrapper.handleRequest("hello", context);
+
+ assertThat(result).isEqualTo("world");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
+ void handlerTracedWithException() {
+ TracingRequestWrapper wrapper =
+ new TracingRequestWrapper(testing.getOpenTelemetrySdk(), WrappedLambda.fromConfiguration());
+ Throwable thrown = catchThrowable(() -> wrapper.handleRequest("goodbye", context));
+
+ assertThat(thrown).isInstanceOf(IllegalArgumentException.class);
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasStatus(StatusData.error())
+ .hasException(thrown)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaWrapperTest$TestRequestHandlerInteger::handleRequest")
+ void handlerTraced_integer() throws IOException {
+ TracingRequestWrapper wrapper =
+ new TracingRequestWrapper(testing.getOpenTelemetrySdk(), WrappedLambda.fromConfiguration());
+ Object result = wrapper.handleRequest(1, context);
+
+ assertThat(result).isEqualTo("world");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"))));
+ }
+
+ @Test
+ @SetEnvironmentVariable(
+ key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
+ value =
+ "io.opentelemetry.instrumentation.awslambdaevents.v3_11.AwsLambdaWrapperTest$TestRequestHandlerCustomType::handleRequest")
+ void handlerTraced_custom() throws IOException {
+ TracingRequestWrapper wrapper =
+ new TracingRequestWrapper(testing.getOpenTelemetrySdk(), WrappedLambda.fromConfiguration());
+ CustomType ct = new CustomType();
+ ct.key = "hello there";
+ ct.value = "General Kenobi";
+ Object result = wrapper.handleRequest(ct, context);
+
+ assertThat(result).isEqualTo("General Kenobi");
+ testing.waitAndAssertTraces(
+ trace ->
+ trace.hasSpansSatisfyingExactly(
+ span ->
+ span.hasName("my_function")
+ .hasKind(SpanKind.SERVER)
+ .hasAttributesSatisfyingExactly(
+ equalTo(
+ CloudIncubatingAttributes.CLOUD_RESOURCE_ID,
+ "arn:aws:lambda:us-east-1:123456789:function:test"),
+ equalTo(CloudIncubatingAttributes.CLOUD_ACCOUNT_ID, "123456789"),
+ equalTo(FaasIncubatingAttributes.FAAS_INVOCATION_ID, "1-22-333"))));
+ }
+
+ public static final class TestRequestHandlerString implements RequestHandler {
+
+ @Override
+ public String handleRequest(String input, Context context) {
+ if (input.equals("hello")) {
+ return "world";
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+
+ public static final class TestRequestHandlerInteger implements RequestHandler {
+
+ @Override
+ public String handleRequest(Integer input, Context context) {
+ if (input == 1) {
+ return "world";
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+
+ static class CustomType {
+ String key;
+ String value;
+
+ // Need getter/setter of all the attributes for serialization/deserialization
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ public static final class TestRequestHandlerCustomType
+ implements RequestHandler {
+
+ @Override
+ public String handleRequest(CustomType input, Context context) {
+ if (input.key.equals("hello there")) {
+ return input.value;
+ }
+ throw new IllegalArgumentException("bad argument");
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperStandardEventsTest.java b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperStandardEventsTest.java
new file mode 100644
index 0000000000..917014df1c
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-3.11/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v3_11/TracingRequestWrapperStandardEventsTest.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.instrumentation.awslambdaevents.v3_11;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
+import com.amazonaws.services.lambda.runtime.events.S3Event;
+import com.amazonaws.services.lambda.runtime.events.SNSEvent;
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
+import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
+import io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal.SerializationUtil;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class TracingRequestWrapperStandardEventsTest {
+ private static final Map, EventInfo> EVENTS_JSON = buildEventExamples();
+
+ private final OpenTelemetrySdk sdk = OpenTelemetrySdk.builder().build();
+ private final Context context = mock(Context.class);
+ private TracingRequestWrapper wrapper;
+
+ static final class EventInfo {
+ final Class> eventType;
+ final String eventBody;
+
+ EventInfo(Class> eventType, String eventBody) {
+ this.eventType = eventType;
+ this.eventBody = eventBody;
+ }
+ }
+
+ private static Map, EventInfo> buildEventExamples() {
+ Map, EventInfo> events = new HashMap<>();
+ events.put(
+ ScheduledEventRequestHandler.class,
+ new EventInfo(
+ ScheduledEvent.class,
+ "{\n"
+ + " \"version\": \"0\",\n"
+ + " \"id\": \"53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa\",\n"
+ + " \"detail-type\": \"Scheduled Event\",\n"
+ + " \"source\": \"aws.events\",\n"
+ + " \"account\": \"123456789012\",\n"
+ + " \"time\": \"2015-10-08T16:53:06Z\",\n"
+ + " \"region\": \"us-east-1\",\n"
+ + " \"resources\": [\n"
+ + " \"arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule\"\n"
+ + " ],\n"
+ + " \"detail\": {}\n"
+ + "}"));
+ events.put(
+ KinesisEventRequestHandler.class,
+ new EventInfo(
+ KinesisEvent.class,
+ "{\n"
+ + " \"Records\": [\n"
+ + " {\n"
+ + " \"kinesis\": {\n"
+ + " \"kinesisSchemaVersion\": \"1.0\",\n"
+ + " \"partitionKey\": \"1\",\n"
+ + " \"sequenceNumber\": \"49590338271490256608559692538361571095921575989136588898\",\n"
+ + " \"data\": \"SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==\",\n"
+ + " \"approximateArrivalTimestamp\": 1545084650.987\n"
+ + " },\n"
+ + " \"eventSource\": \"aws:kinesis\",\n"
+ + " \"eventVersion\": \"1.0\",\n"
+ + " \"eventID\": \"shardId-000000000006:49590338271490256608559692538361571095921575989136588898\",\n"
+ + " \"eventName\": \"aws:kinesis:record\",\n"
+ + " \"invokeIdentityArn\": \"arn:aws:iam::123456789012:role/lambda-role\",\n"
+ + " \"awsRegion\": \"us-east-2\",\n"
+ + " \"eventSourceARN\": \"arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"kinesis\": {\n"
+ + " \"kinesisSchemaVersion\": \"1.0\",\n"
+ + " \"partitionKey\": \"1\",\n"
+ + " \"sequenceNumber\": \"49590338271490256608559692540925702759324208523137515618\",\n"
+ + " \"data\": \"VGhpcyBpcyBvbmx5IGEgdGVzdC4=\",\n"
+ + " \"approximateArrivalTimestamp\": 1545084711.166\n"
+ + " },\n"
+ + " \"eventSource\": \"aws:kinesis\",\n"
+ + " \"eventVersion\": \"1.0\",\n"
+ + " \"eventID\": \"shardId-000000000006:49590338271490256608559692540925702759324208523137515618\",\n"
+ + " \"eventName\": \"aws:kinesis:record\",\n"
+ + " \"invokeIdentityArn\": \"arn:aws:iam::123456789012:role/lambda-role\",\n"
+ + " \"awsRegion\": \"us-east-2\",\n"
+ + " \"eventSourceARN\": \"arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream\"\n"
+ + " }\n"
+ + " ]\n"
+ + "}"));
+ events.put(
+ SqsEventRequestHandler.class,
+ new EventInfo(
+ SQSEvent.class,
+ "{\n"
+ + " \"Records\": [\n"
+ + " {\n"
+ + " \"messageId\": \"059f36b4-87a3-44ab-83d2-661975830a7d\",\n"
+ + " \"receiptHandle\": \"AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...\",\n"
+ + " \"body\": \"Test message.\",\n"
+ + " \"attributes\": {\n"
+ + " \"ApproximateReceiveCount\": \"1\",\n"
+ + " \"SentTimestamp\": \"1545082649183\",\n"
+ + " \"SenderId\": \"AIDAIENQZJOLO23YVJ4VO\",\n"
+ + " \"ApproximateFirstReceiveTimestamp\": \"1545082649185\"\n"
+ + " },\n"
+ + " \"messageAttributes\": {},\n"
+ + " \"md5OfBody\": \"e4e68fb7bd0e697a0ae8f1bb342846b3\",\n"
+ + " \"eventSource\": \"aws:sqs\",\n"
+ + " \"eventSourceARN\": \"arn:aws:sqs:us-east-2:123456789012:my-queue\",\n"
+ + " \"awsRegion\": \"us-east-2\"\n"
+ + " },\n"
+ + " {\n"
+ + " \"messageId\": \"2e1424d4-f796-459a-8184-9c92662be6da\",\n"
+ + " \"receiptHandle\": \"AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...\",\n"
+ + " \"body\": \"Test message.\",\n"
+ + " \"attributes\": {\n"
+ + " \"ApproximateReceiveCount\": \"1\",\n"
+ + " \"SentTimestamp\": \"1545082650636\",\n"
+ + " \"SenderId\": \"AIDAIENQZJOLO23YVJ4VO\",\n"
+ + " \"ApproximateFirstReceiveTimestamp\": \"1545082650649\"\n"
+ + " },\n"
+ + " \"messageAttributes\": {},\n"
+ + " \"md5OfBody\": \"e4e68fb7bd0e697a0ae8f1bb342846b3\",\n"
+ + " \"eventSource\": \"aws:sqs\",\n"
+ + " \"eventSourceARN\": \"arn:aws:sqs:us-east-2:123456789012:my-queue\",\n"
+ + " \"awsRegion\": \"us-east-2\"\n"
+ + " }\n"
+ + " ]\n"
+ + "}"));
+ events.put(
+ S3EventRequestHandler.class,
+ new EventInfo(
+ S3Event.class,
+ "{\n"
+ + " \"Records\": [\n"
+ + " {\n"
+ + " \"eventVersion\": \"2.1\",\n"
+ + " \"eventSource\": \"aws:s3\",\n"
+ + " \"awsRegion\": \"us-east-2\",\n"
+ + " \"eventTime\": \"2019-09-03T19:37:27.192Z\",\n"
+ + " \"eventName\": \"ObjectCreated:Put\",\n"
+ + " \"userIdentity\": {\n"
+ + " \"principalId\": \"AWS:AIDAINPONIXQXHT3IKHL2\"\n"
+ + " },\n"
+ + " \"requestParameters\": {\n"
+ + " \"sourceIPAddress\": \"205.255.255.255\"\n"
+ + " },\n"
+ + " \"responseElements\": {\n"
+ + " \"x-amz-request-id\": \"D82B88E5F771F645\",\n"
+ + " \"x-amz-id-2\": \"vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo=\"\n"
+ + " },\n"
+ + " \"s3\": {\n"
+ + " \"s3SchemaVersion\": \"1.0\",\n"
+ + " \"configurationId\": \"828aa6fc-f7b5-4305-8584-487c791949c1\",\n"
+ + " \"bucket\": {\n"
+ + " \"name\": \"DOC-EXAMPLE-BUCKET\",\n"
+ + " \"ownerIdentity\": {\n"
+ + " \"principalId\": \"A3I5XTEXAMAI3E\"\n"
+ + " },\n"
+ + " \"arn\": \"arn:aws:s3:::lambda-artifacts-deafc19498e3f2df\"\n"
+ + " },\n"
+ + " \"object\": {\n"
+ + " \"key\": \"b21b84d653bb07b05b1e6b33684dc11b\",\n"
+ + " \"size\": 1305107,\n"
+ + " \"eTag\": \"b21b84d653bb07b05b1e6b33684dc11b\",\n"
+ + " \"sequencer\": \"0C0F6F405D6ED209E1\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}"));
+ events.put(
+ SnsEventRequestHandler.class,
+ new EventInfo(
+ SNSEvent.class,
+ "{\n"
+ + " \"Records\": [\n"
+ + " {\n"
+ + " \"EventVersion\": \"1.0\",\n"
+ + " \"EventSubscriptionArn\": \"arn:aws:sns:us-east-2:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486\",\n"
+ + " \"EventSource\": \"aws:sns\",\n"
+ + " \"Sns\": {\n"
+ + " \"SignatureVersion\": \"1\",\n"
+ + " \"Timestamp\": \"2019-01-02T12:45:07.000Z\",\n"
+ + " \"Signature\": \"tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==\",\n"
+ + " \"SigningCertUrl\": \"https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem\",\n"
+ + " \"MessageId\": \"95df01b4-ee98-5cb9-9903-4c221d41eb5e\",\n"
+ + " \"Message\": \"Hello from SNS!\",\n"
+ + " \"MessageAttributes\": {\n"
+ + " \"Test\": {\n"
+ + " \"Type\": \"String\",\n"
+ + " \"Value\": \"TestString\"\n"
+ + " },\n"
+ + " \"TestBinary\": {\n"
+ + " \"Type\": \"Binary\",\n"
+ + " \"Value\": \"TestBinary\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"Type\": \"Notification\",\n"
+ + " \"UnsubscribeUrl\": \"https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486\",\n"
+ + " \"TopicArn\":\"arn:aws:sns:us-east-2:123456789012:sns-lambda\",\n"
+ + " \"Subject\": \"TestInvoke\"\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}"));
+ return events;
+ }
+
+ private TracingRequestWrapper buildWrapper(Class> targetClass) {
+ WrappedLambda wrappedLambda = new WrappedLambda(targetClass, "handleRequest");
+
+ return new TracingRequestWrapper(sdk, wrappedLambda);
+ }
+
+ @ParameterizedTest
+ @ValueSource(
+ classes = {
+ ScheduledEventRequestHandler.class,
+ KinesisEventRequestHandler.class,
+ SqsEventRequestHandler.class,
+ S3EventRequestHandler.class,
+ SnsEventRequestHandler.class
+ })
+ void handleLambdaEvent(Class> targetClass) throws IOException {
+ wrapper = buildWrapper(targetClass);
+ EventInfo eventInfo = EVENTS_JSON.get(targetClass);
+
+ Object input = SerializationUtil.fromJson(eventInfo.eventBody, eventInfo.eventType);
+
+ // Call to object based "O handleRequest(I input, Context context)" method
+ // delegates to the stream based
+ // "handleRequest(InputStream input, OutputStream output, Context context)" method.
+ // So serialization/deserialization of both input and outputs are triggered to be verified here.
+ Object output = wrapper.handleRequest(input, context);
+
+ assertThat(input.getClass()).isEqualTo(output.getClass());
+
+ // "equals" methods are not properly implemented of Lambda events,
+ // so we are comparing them over their serialized json data
+ String inputJson = SerializationUtil.toJson(input);
+ String outputJson = SerializationUtil.toJson(output);
+ assertThat(inputJson).isEqualTo(outputJson);
+ }
+
+ public static class ScheduledEventRequestHandler
+ implements RequestHandler {
+ @Override
+ public ScheduledEvent handleRequest(ScheduledEvent i, Context cntxt) {
+ return i;
+ }
+ }
+
+ public static class KinesisEventRequestHandler
+ implements RequestHandler {
+ @Override
+ public KinesisEvent handleRequest(KinesisEvent i, Context cntxt) {
+ return i;
+ }
+ }
+
+ public static class SqsEventRequestHandler implements RequestHandler {
+ @Override
+ public SQSEvent handleRequest(SQSEvent i, Context cntxt) {
+ return i;
+ }
+ }
+
+ public static class S3EventRequestHandler implements RequestHandler {
+ @Override
+ public S3Event handleRequest(S3Event i, Context cntxt) {
+ return i;
+ }
+ }
+
+ public static class SnsEventRequestHandler implements RequestHandler {
+ @Override
+ public SNSEvent handleRequest(SNSEvent i, Context cntxt) {
+ return i;
+ }
+ }
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/build.gradle.kts
new file mode 100644
index 0000000000..0e52a2231c
--- /dev/null
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/build.gradle.kts
@@ -0,0 +1,41 @@
+plugins {
+ id("otel.library-instrumentation")
+}
+
+dependencies {
+ api(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
+
+ compileOnly("io.opentelemetry:opentelemetry-sdk")
+ compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
+
+ library("com.amazonaws:aws-lambda-java-core:1.0.0")
+ // First version to includes support for SQSEvent, currently the most popular message queue used
+ // with lambda.
+ // NB: 2.2.0 includes a class called SQSEvent but isn't usable due to it returning private classes
+ // in public API.
+ library("com.amazonaws:aws-lambda-java-events:2.2.1")
+
+ // By default, "aws-lambda-java-serialization" library is enabled in the classpath
+ // at the AWS Lambda environment except "java8" runtime which is deprecated.
+ // But it is available at "java8.al2" runtime, so it is still can be used
+ // by Java 8 based Lambda functions.
+ // So that is the reason that why we add it as compile only dependency.
+ library("com.amazonaws:aws-lambda-java-serialization:1.1.5")
+
+ // We need Jackson for wrappers to reproduce the serialization does when Lambda invokes a RequestHandler with event
+ // since Lambda will only be able to invoke the wrapper itself with a generic Object.
+ // Note that Lambda itself uses Jackson, but does not expose it to the function so we need to include it here.
+ // TODO: Switch to aws-lambda-java-serialization to more robustly follow Lambda's serialization logic.
+ implementation("com.fasterxml.jackson.core:jackson-databind")
+ implementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator")
+
+ // allows to get the default events
+ testLibrary("com.amazonaws:aws-lambda-java-events:3.10.0")
+}
+
+tasks.withType().configureEach {
+ // required on jdk17
+ jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
+ jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED")
+ jvmArgs("-XX:+IgnoreUnrecognizedVMOptions")
+}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/ApiGatewayProxyAttributesExtractor.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/ApiGatewayProxyAttributesExtractor.java
similarity index 98%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/ApiGatewayProxyAttributesExtractor.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/ApiGatewayProxyAttributesExtractor.java
index 36f8dcd0b5..5413f1b09b 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/ApiGatewayProxyAttributesExtractor.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/ApiGatewayProxyAttributesExtractor.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorUtil.internalSet;
import static io.opentelemetry.instrumentation.api.internal.HttpConstants._OTHER;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java
similarity index 86%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java
index 502a8e016d..e5d6151132 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaEventsInstrumenterFactory.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import io.opentelemetry.api.OpenTelemetry;
@@ -21,13 +21,11 @@ import java.util.Set;
public final class AwsLambdaEventsInstrumenterFactory {
public static AwsLambdaFunctionInstrumenter createInstrumenter(
- OpenTelemetry openTelemetry, Set knownMethods) {
+ OpenTelemetry openTelemetry, String instrumentationName, Set knownMethods) {
return new AwsLambdaFunctionInstrumenter(
openTelemetry,
Instrumenter.builder(
- openTelemetry,
- "io.opentelemetry.aws-lambda-events-2.2",
- AwsLambdaEventsInstrumenterFactory::spanName)
+ openTelemetry, instrumentationName, AwsLambdaEventsInstrumenterFactory::spanName)
.addAttributesExtractor(new AwsLambdaFunctionAttributesExtractor())
.addAttributesExtractor(new ApiGatewayProxyAttributesExtractor(knownMethods))
.buildInstrumenter(SpanKindExtractor.alwaysServer()));
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java
similarity index 77%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java
index 4cd11fc0c4..e4ce0be1a9 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/AwsLambdaSqsInstrumenterFactory.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
@@ -18,21 +18,19 @@ import java.util.List;
*/
public final class AwsLambdaSqsInstrumenterFactory {
- public static Instrumenter forEvent(OpenTelemetry openTelemetry) {
+ public static Instrumenter forEvent(
+ OpenTelemetry openTelemetry, String instrumentationName) {
return Instrumenter.builder(
- openTelemetry,
- "io.opentelemetry.aws-lambda-events-2.2",
- AwsLambdaSqsInstrumenterFactory::spanName)
+ openTelemetry, instrumentationName, AwsLambdaSqsInstrumenterFactory::spanName)
.addAttributesExtractor(new SqsEventAttributesExtractor())
.addSpanLinksExtractor(new SqsEventSpanLinksExtractor())
.buildInstrumenter(SpanKindExtractor.alwaysConsumer());
}
- public static Instrumenter forMessage(OpenTelemetry openTelemetry) {
+ public static Instrumenter forMessage(
+ OpenTelemetry openTelemetry, String instrumentationName) {
return Instrumenter.builder(
- openTelemetry,
- "io.opentelemetry.aws-lambda-events-2.2",
- message -> message.getEventSource() + " process")
+ openTelemetry, instrumentationName, message -> message.getEventSource() + " process")
.addAttributesExtractor(new SqsMessageAttributesExtractor())
.addSpanLinksExtractor(new SqsMessageSpanLinksExtractor())
.buildInstrumenter(SpanKindExtractor.alwaysConsumer());
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/CustomJodaModule.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/CustomJodaModule.java
similarity index 96%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/CustomJodaModule.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/CustomJodaModule.java
index 1be598ae8f..5be884879c 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/CustomJodaModule.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/CustomJodaModule.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
@@ -34,7 +34,6 @@ class CustomJodaModule extends SimpleModule {
private static final long serialVersionUID = 1L;
public CustomJodaModule() {
- super();
addDeserializer(DateTime.class, new DateTimeDeserialiser());
}
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParameters.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParameters.java
similarity index 81%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParameters.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParameters.java
index 53e68280ba..7e27bed622 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParameters.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParameters.java
@@ -3,16 +3,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.Context;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.function.BiFunction;
-final class LambdaParameters {
+/**
+ * This class is internal and is hence not for public use. Its APIs are unstable and can change at
+ * any time.
+ */
+public final class LambdaParameters {
- static Object[] toArray(
+ public static Object[] toArray(
Method targetMethod, T input, Context context, BiFunction, Object> mapper) {
Class>[] parameterTypes = targetMethod.getParameterTypes();
Object[] parameters = new Object[parameterTypes.length];
@@ -28,7 +32,7 @@ final class LambdaParameters {
return parameters;
}
- static Object[] toParameters(Method targetMethod, T input, Context context) {
+ public static Object[] toParameters(Method targetMethod, T input, Context context) {
Class>[] parameterTypes = targetMethod.getParameterTypes();
Object[] parameters = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
@@ -43,7 +47,7 @@ final class LambdaParameters {
return parameters;
}
- static Object toInput(
+ public static Object toInput(
Method targetMethod,
InputStream inputStream,
BiFunction, Object> mapper) {
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtil.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtil.java
similarity index 98%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtil.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtil.java
index 81649340e6..e8c1e88fb7 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtil.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtil.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer;
import com.amazonaws.services.lambda.runtime.serialization.events.LambdaEventSerializers;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventAttributesExtractor.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventAttributesExtractor.java
similarity index 94%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventAttributesExtractor.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventAttributesExtractor.java
index a29b6a7c4c..debabc8c76 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventAttributesExtractor.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventAttributesExtractor.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.api.common.AttributeKey;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventSpanLinksExtractor.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventSpanLinksExtractor.java
similarity index 90%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventSpanLinksExtractor.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventSpanLinksExtractor.java
index afb01ec984..131f1c15ca 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsEventSpanLinksExtractor.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsEventSpanLinksExtractor.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.context.Context;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageAttributesExtractor.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageAttributesExtractor.java
similarity index 95%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageAttributesExtractor.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageAttributesExtractor.java
index 8962dfe08f..975f423787 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageAttributesExtractor.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageAttributesExtractor.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
import io.opentelemetry.api.common.AttributeKey;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageSpanLinksExtractor.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageSpanLinksExtractor.java
similarity index 96%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageSpanLinksExtractor.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageSpanLinksExtractor.java
index 305e3e62a0..9c628fe89b 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SqsMessageSpanLinksExtractor.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/main/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SqsMessageSpanLinksExtractor.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
import io.opentelemetry.api.trace.Span;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParametersTest.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParametersTest.java
similarity index 97%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParametersTest.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParametersTest.java
index f738b5a349..efa49d7665 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/LambdaParametersTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/LambdaParametersTest.java
@@ -3,13 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import com.amazonaws.services.lambda.runtime.Context;
-import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.SerializationUtil;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtilTest.java b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtilTest.java
similarity index 99%
rename from instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtilTest.java
rename to instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtilTest.java
index 7711d15779..fe2df60c90 100644
--- a/instrumentation/aws-lambda/aws-lambda-events-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/v2_2/internal/SerializationUtilTest.java
+++ b/instrumentation/aws-lambda/aws-lambda-events-common-2.2/library/src/test/java/io/opentelemetry/instrumentation/awslambdaevents/common/v2_2/internal/SerializationUtilTest.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
+package io.opentelemetry.instrumentation.awslambdaevents.common.v2_2.internal;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 163720f93e..52d6bafdd8 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -164,6 +164,8 @@ include(":instrumentation:aws-lambda:aws-lambda-core-1.0:testing")
include(":instrumentation:aws-lambda:aws-lambda-events-2.2:javaagent")
include(":instrumentation:aws-lambda:aws-lambda-events-2.2:library")
include(":instrumentation:aws-lambda:aws-lambda-events-2.2:testing")
+include(":instrumentation:aws-lambda:aws-lambda-events-3.11:library")
+include(":instrumentation:aws-lambda:aws-lambda-events-common-2.2:library")
include(":instrumentation:aws-sdk:aws-sdk-1.11:javaagent")
include(":instrumentation:aws-sdk:aws-sdk-1.11:library")
include(":instrumentation:aws-sdk:aws-sdk-1.11:library-autoconfigure")