Split lambda instrumentation into core and events (#5326)

* Split out lambda core instrumentation

* More

* Remove request wrapper from core

* Split events

* Dedupe

* More

* More renames

* Finish

* Clean

* README

* Rename more

* Finish

* Fix README

* Fix README

* Fix

* Comments
This commit is contained in:
Anuraag Agrawal 2022-02-11 10:27:22 +09:00 committed by GitHub
parent 51b88c7bce
commit f236b2d4c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 774 additions and 246 deletions

View File

@ -1,32 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambda.v1_0;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaSqsInstrumenterFactory;
public final class AwsLambdaInstrumentationHelper {
private static final AwsLambdaFunctionInstrumenter FUNCTION_INSTRUMENTER =
AwsLambdaFunctionInstrumenterFactory.createInstrumenter(GlobalOpenTelemetry.get());
public static AwsLambdaFunctionInstrumenter functionInstrumenter() {
return FUNCTION_INSTRUMENTER;
}
private static final Instrumenter<SQSEvent, Void> MESSAGE_TRACER =
AwsLambdaSqsInstrumenterFactory.forEvent(GlobalOpenTelemetry.get());
public static Instrumenter<SQSEvent, Void> messageInstrumenter() {
return MESSAGE_TRACER;
}
private AwsLambdaInstrumentationHelper() {}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStream;
import java.util.Map;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class HeadersFactory {
private static final Logger logger = LoggerFactory.getLogger(HeadersFactory.class);
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Nullable
static Map<String, String> ofStream(InputStream inputStream) {
try (JsonParser jParser = new JsonFactory().createParser(inputStream)) {
while (jParser.nextToken() != null) {
String name = jParser.getCurrentName();
if ("headers".equalsIgnoreCase(name)) {
jParser.nextToken();
@SuppressWarnings("unchecked")
Map<String, String> map =
(Map<String, String>) OBJECT_MAPPER.readValue(jParser, Map.class);
return map;
}
}
} catch (Exception e) {
logger.debug("Could not get headers from request, ", e);
}
return null;
}
private HeadersFactory() {}
}

View File

@ -0,0 +1,11 @@
# AWS Lambda Instrumentation
We provide two packages for instrumenting AWS lambda functions.
- [aws-lambda-core-1.0](./aws-lambda-core-1.0/library) provides lightweight instrumentation of the Lambda core library, supporting
all versions. Use this package if you only use `RequestStreamHandler` or know you don't use any event classes from
`aws-lambda-java-events`. This also includes when you are using `aws-serverless-java-container` to run e.g., a
Spring Boot application on Lambda.
- [aws-lambda-events-2.2](./aws-lambda-events-2.2/library) provides full instrumentation of the Lambda library, including standard
and custom event types, from `aws-lambda-java-events` 2.2+.

View File

@ -0,0 +1,21 @@
plugins {
id("otel.javaagent-instrumentation")
}
muzzle {
pass {
group.set("com.amazonaws")
module.set("aws-lambda-java-core")
versions.set("[1.0.0,)")
extraDependency("com.amazonaws.serverless:aws-serverless-java-container-core:1.5.2")
}
}
dependencies {
implementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
library("com.amazonaws:aws-lambda-java-core:1.0.0")
testImplementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:testing"))
testInstrumentation(project(":instrumentation:aws-lambda:aws-lambda-events-2.2:javaagent"))
}

View File

@ -0,0 +1,22 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
public final class AwsLambdaInstrumentationHelper {
private static final AwsLambdaFunctionInstrumenter FUNCTION_INSTRUMENTER =
AwsLambdaFunctionInstrumenterFactory.createInstrumenter(GlobalOpenTelemetry.get());
public static AwsLambdaFunctionInstrumenter functionInstrumenter() {
return FUNCTION_INSTRUMENTER;
}
private AwsLambdaInstrumentationHelper() {}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambda.v1_0;
package io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0;
import static java.util.Collections.singletonList;
@ -15,7 +15,7 @@ import java.util.List;
@AutoService(InstrumentationModule.class)
public class AwsLambdaInstrumentationModule extends InstrumentationModule {
public AwsLambdaInstrumentationModule() {
super("aws-lambda", "aws-lambda-1.0");
super("aws-lambda", "aws-lambda-core-1.0");
}
@Override

View File

@ -0,0 +1,88 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0.AwsLambdaInstrumentationHelper.functionInstrumenter;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.amazonaws.services.lambda.runtime.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.api.OpenTelemetrySdkAccess;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing;
import net.bytebuddy.matcher.ElementMatcher;
public class AwsLambdaRequestHandlerInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderOptimization() {
return hasClassesNamed("com.amazonaws.services.lambda.runtime.RequestHandler");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named("com.amazonaws.services.lambda.runtime.RequestHandler"));
}
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
isMethod()
.and(isPublic())
.and(named("handleRequest"))
.and(takesArgument(1, named("com.amazonaws.services.lambda.runtime.Context"))),
AwsLambdaRequestHandlerInstrumentation.class.getName() + "$HandleRequestAdvice");
}
@SuppressWarnings("unused")
public static class HandleRequestAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(value = 0, typing = Typing.DYNAMIC) Object arg,
@Advice.Argument(1) Context context,
@Advice.Local("otelInput") AwsLambdaRequest input,
@Advice.Local("otelContext") io.opentelemetry.context.Context otelContext,
@Advice.Local("otelScope") Scope otelScope) {
input = AwsLambdaRequest.create(context, arg, Collections.emptyMap());
io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(input);
if (!functionInstrumenter().shouldStart(parentContext, input)) {
return;
}
otelContext = functionInstrumenter().start(parentContext, input);
otelScope = otelContext.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Argument(value = 0, typing = Typing.DYNAMIC) Object arg,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelInput") AwsLambdaRequest input,
@Advice.Local("otelContext") io.opentelemetry.context.Context functionContext,
@Advice.Local("otelScope") Scope functionScope) {
if (functionScope != null) {
functionScope.close();
functionInstrumenter().end(functionContext, input, null, throwable);
}
OpenTelemetrySdkAccess.forceFlush(1, TimeUnit.SECONDS);
}
}
}

View File

@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambda.v1_0;
package io.opentelemetry.javaagent.instrumentation.awslambdacore.v1_0;
import static org.assertj.core.api.Assertions.assertThat;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import io.opentelemetry.instrumentation.awslambda.v1_0.AbstractAwsLambdaTest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AbstractAwsLambdaTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.AfterEach;

View File

@ -0,0 +1,95 @@
# 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 1 second), please configure `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` env property. The value is in seconds.
Available wrappers:
- `io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestStreamWrapper` - for wrapping streaming handlers (implementing `RequestStreamHandler`), enabling HTTP context propagation for HTTP requests
When using known Lambda event types as parameters, use [aws-lambda-events-2.2](../../aws-lambda-events-2.2/library).
## 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<String, String> {
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
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-trace-propagators</artifactId>
<version>0.8.0</version>
</dependency>
</dependencies>
```
## 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 explicitely.
### 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 https://github.com/open-telemetry/opentelemetry-java/tree/main/extensions/trace_propagators).
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 descibed [here](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#propagator).

View File

@ -0,0 +1,33 @@
plugins {
id("otel.library-instrumentation")
}
dependencies {
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")
implementation("io.opentelemetry:opentelemetry-extension-aws")
// We do lightweight parsing of JSON to extract HTTP headers from requests for propagation.
// This will be commonly needed even for users that don't use events, but luckily it's not too big.
// Note that Lambda itself uses Jackson, but does not expose it to the function so we need to include
// it here.
implementation("com.fasterxml.jackson.core:jackson-core")
// 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.google.guava:guava")
testImplementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:testing"))
testImplementation("org.mockito:mockito-core")
testImplementation("org.assertj:assertj-core")
testImplementation("uk.org.webcompere:system-stubs-jupiter")
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import com.google.auto.value.AutoValue;

View File

@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import java.lang.reflect.Method;
final class LambdaParameters {
static <T> Object[] toArray(Method targetMethod, T input, Context context) {
Class<?>[] parameterTypes = targetMethod.getParameterTypes();
Object[] parameters = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> clazz = parameterTypes[i];
boolean isContext = clazz.equals(Context.class);
if (isContext) {
parameters[i] = context;
} else if (i == 0) {
parameters[0] = input;
}
}
return parameters;
}
private LambdaParameters() {}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode;

View File

@ -3,14 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.time.Duration;
import java.util.Collections;
@ -64,18 +63,9 @@ public abstract class TracingRequestHandler<I, O> implements RequestHandler<I, O
this.instrumenter = instrumenter;
}
private Map<String, String> getHeaders(I input) {
Map<String, String> result = null;
if (input instanceof APIGatewayProxyRequestEvent) {
APIGatewayProxyRequestEvent event = (APIGatewayProxyRequestEvent) input;
result = event.getHeaders();
}
return result == null ? Collections.emptyMap() : result;
}
@Override
public final O handleRequest(I input, Context context) {
AwsLambdaRequest request = AwsLambdaRequest.create(context, input, getHeaders(input));
AwsLambdaRequest request = AwsLambdaRequest.create(context, input, extractHttpHeaders(input));
io.opentelemetry.context.Context parentContext = instrumenter.extract(request);
if (!instrumenter.shouldStart(parentContext, request)) {
@ -98,4 +88,12 @@ public abstract class TracingRequestHandler<I, O> implements RequestHandler<I, O
}
protected abstract O doHandleRequest(I input, Context context);
/**
* Returns the HTTP headers for the request extracted from the request handler's input. By
* default, returns empty headers.
*/
protected Map<String, String> extractHttpHeaders(I input) {
return Collections.emptyMap();
}
}

View File

@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.ApiGatewayProxyRequest;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.ApiGatewayProxyRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenterFactory;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.io.IOException;
import java.io.InputStream;

View File

@ -3,10 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrapperConfiguration;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import java.io.IOException;

View File

@ -3,19 +3,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static io.opentelemetry.instrumentation.awslambda.v1_0.internal.HeadersFactory.ofStream;
import static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.HeadersFactory.ofStream;
import io.opentelemetry.api.GlobalOpenTelemetry;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils;
*/
public abstract class ApiGatewayProxyRequest {
private static final Logger logger = LoggerFactory.getLogger(ApiGatewayProxyRequest.class);
// TODO(anuraaga): We should create a RequestFactory type of class instead of evaluating this
// for every request.
private static boolean noHttpPropagationNeeded() {
@ -38,8 +40,7 @@ public abstract class ApiGatewayProxyRequest {
fields.iterator().next());
}
public static ApiGatewayProxyRequest forStream(InputStream source) throws IOException {
public static ApiGatewayProxyRequest forStream(InputStream source) {
if (noHttpPropagationNeeded()) {
return new NoopRequest(source);
}
@ -47,8 +48,14 @@ public abstract class ApiGatewayProxyRequest {
if (source.markSupported()) {
return new MarkableApiGatewayProxyRequest(source);
}
// fallback
return new CopiedApiGatewayProxyRequest(source);
// It is known that the Lambda runtime passes ByteArrayInputStream's to functions, so gracefully
// handle this without propagating and revisit if getting user reports that expectations
// changed.
logger.warn(
"HTTP propagation enabled but could not extract HTTP headers. "
+ "This is a bug in the OpenTelemetry AWS Lambda instrumentation. Type of request stream {}",
source.getClass());
return new NoopRequest(source);
}
@Nullable
@ -89,24 +96,9 @@ public abstract class ApiGatewayProxyRequest {
@Override
public InputStream freshStream() throws IOException {
inputStream.reset();
inputStream.mark(Integer.MAX_VALUE);
return inputStream;
}
}
private static class CopiedApiGatewayProxyRequest extends ApiGatewayProxyRequest {
private final byte[] data;
private CopiedApiGatewayProxyRequest(InputStream inputStream) throws IOException {
data = IOUtils.toByteArray(inputStream);
}
@Override
public InputStream freshStream() {
return new ByteArrayInputStream(data);
}
}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.CLOUD_ACCOUNT_ID;
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.FAAS_ID;
@ -12,13 +12,17 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.FAAS_
import com.amazonaws.services.lambda.runtime.Context;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import javax.annotation.Nullable;
class AwsLambdaFunctionAttributesExtractor
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class AwsLambdaFunctionAttributesExtractor
implements AttributesExtractor<AwsLambdaRequest, Object> {
@Nullable private static final MethodHandle GET_FUNCTION_ARN;

View File

@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.internal.ContextPropagationDebug;
import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import java.util.Map;
import javax.annotation.Nullable;
@ -23,7 +23,7 @@ public class AwsLambdaFunctionInstrumenter {
private final OpenTelemetry openTelemetry;
final Instrumenter<AwsLambdaRequest, Object> instrumenter;
AwsLambdaFunctionInstrumenter(
public AwsLambdaFunctionInstrumenter(
OpenTelemetry openTelemetry, Instrumenter<AwsLambdaRequest, Object> instrumenter) {
this.openTelemetry = openTelemetry;
this.instrumenter = instrumenter;

View File

@ -0,0 +1,33 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public class AwsLambdaFunctionInstrumenterFactory {
public static AwsLambdaFunctionInstrumenter createInstrumenter(OpenTelemetry openTelemetry) {
return new AwsLambdaFunctionInstrumenter(
openTelemetry,
Instrumenter.builder(
openTelemetry,
"io.opentelemetry.aws-lambda-core-1.0",
AwsLambdaFunctionInstrumenterFactory::spanName)
.addAttributesExtractors(new AwsLambdaFunctionAttributesExtractor())
.newInstrumenter(SpanKindExtractor.alwaysServer()));
}
private static String spanName(AwsLambdaRequest input) {
return input.getAwsContext().getFunctionName();
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class HeadersFactory {
private static final Logger logger = LoggerFactory.getLogger(HeadersFactory.class);
private static final JsonFactory JSON_FACTORY = new JsonFactory();
static Map<String, String> ofStream(InputStream inputStream) {
try (JsonParser parser = JSON_FACTORY.createParser(inputStream)) {
parser.nextToken();
if (!parser.isExpectedStartObjectToken()) {
logger.debug("Not a JSON object");
return Collections.emptyMap();
}
while (parser.nextToken() != JsonToken.END_OBJECT) {
parser.nextToken();
if (!parser.getCurrentName().equals("headers")) {
parser.skipChildren();
continue;
}
if (!parser.isExpectedStartObjectToken()) {
logger.debug("Invalid JSON for HTTP headers");
return Collections.emptyMap();
}
Map<String, String> headers = new HashMap<>();
while (parser.nextToken() != JsonToken.END_OBJECT) {
String value = parser.nextTextValue();
if (value != null) {
headers.put(parser.getCurrentName(), value);
}
}
return headers;
}
} catch (Exception e) {
logger.debug("Could not get headers from request, ", e);
}
return Collections.emptyMap();
}
private HeadersFactory() {}
}

View File

@ -3,21 +3,25 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
final class MapUtils {
static Map<String, String> lowercaseMap(Map<String, String> source) {
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class MapUtils {
public static Map<String, String> lowercaseMap(Map<String, String> source) {
return emptyIfNull(source).entrySet().stream()
.filter(e -> e.getKey() != null)
.collect(Collectors.toMap(e -> e.getKey().toLowerCase(Locale.ROOT), Map.Entry::getValue));
}
static Map<String, String> emptyIfNull(Map<String, String> map) {
public static Map<String, String> emptyIfNull(Map<String, String> map) {
return map == null ? Collections.emptyMap() : map;
}

View File

@ -3,9 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static io.opentelemetry.instrumentation.awslambda.v1_0.internal.MapUtils.lowercaseMap;
import static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils.lowercaseMap;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
@ -16,7 +16,11 @@ import java.util.Collections;
import java.util.Locale;
import java.util.Map;
final class ParentContextExtractor {
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class ParentContextExtractor {
private static final String AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID";
@ -50,7 +54,7 @@ final class ParentContextExtractor {
// lower-case map getter used for extraction
static final String AWS_TRACE_HEADER_PROPAGATOR_KEY = "x-amzn-trace-id";
static Context fromXrayHeader(String parentHeader) {
public static Context fromXrayHeader(String parentHeader) {
return AwsXrayPropagator.getInstance()
.extract(
// see BaseTracer#extract() on why we're using root() here

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import com.amazonaws.services.lambda.runtime.Context;
import java.lang.reflect.Constructor;
@ -14,8 +14,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/** Model for wrapped lambda function (object, class, method). */
class WrappedLambda {
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class WrappedLambda {
public static final String OTEL_LAMBDA_HANDLER_ENV_KEY =
"OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER";
@ -28,7 +31,7 @@ class WrappedLambda {
* Creates new lambda wrapper out of configuration. Supported env properties: - {@value
* OTEL_LAMBDA_HANDLER_ENV_KEY} - lambda handler in format: package.ClassName::methodName
*/
static WrappedLambda fromConfiguration() {
public static WrappedLambda fromConfiguration() {
String lambdaHandler = System.getenv(OTEL_LAMBDA_HANDLER_ENV_KEY);
if (lambdaHandler == null || lambdaHandler.isEmpty()) {
@ -53,7 +56,8 @@ class WrappedLambda {
return new WrappedLambda(targetClass, targetMethodName);
}
WrappedLambda(Class<?> targetClass, String targetMethodName) {
// Visible for testing
public WrappedLambda(Class<?> targetClass, String targetMethodName) {
this.targetClass = targetClass;
this.targetMethodName = targetMethodName;
this.targetObject = instantiateTargetClass();
@ -86,7 +90,7 @@ class WrappedLambda {
return parameters[parameters.length - 1].getType().equals(Context.class);
}
Method getRequestTargetMethod() {
public Method getRequestTargetMethod() {
List<Method> methods = Arrays.asList(targetClass.getMethods());
Optional<Method> firstOptional =
@ -150,11 +154,11 @@ class WrappedLambda {
return 0;
}
Object getTargetObject() {
public Object getTargetObject() {
return targetObject;
}
Class<?> getTargetClass() {
public Class<?> getTargetClass() {
return targetClass;
}
}

View File

@ -3,10 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import java.time.Duration;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class WrapperConfiguration {
private WrapperConfiguration() {}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
@ -12,9 +12,11 @@ import static org.mockito.Mockito.when;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
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.testing.assertj.OpenTelemetryAssertions;
@ -42,11 +44,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaStreamWrapperHttpPropagationTest$TestRequestHandler::handleRequest")
"io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaStreamWrapperHttpPropagationTest$TestRequestHandler::handleRequest")
public class AwsLambdaStreamWrapperHttpPropagationTest {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@RegisterExtension
public static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();
@ -143,11 +143,24 @@ public class AwsLambdaStreamWrapperHttpPropagationTest {
public static final class TestRequestHandler implements RequestStreamHandler {
private static final JsonFactory JSON_FACTORY = new JsonFactory();
@Override
public void handleRequest(InputStream input, OutputStream output, Context context)
throws IOException {
JsonNode root = OBJECT_MAPPER.readTree(input);
String body = root.get("body").asText();
String body = "";
try (JsonParser parser = JSON_FACTORY.createParser(input)) {
parser.nextToken();
while (parser.nextToken() != JsonToken.END_OBJECT) {
parser.nextToken();
if (!parser.getCurrentName().equals("body")) {
parser.skipChildren();
continue;
}
body = parser.getText();
break;
}
}
BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
if (body.equals("hello")) {

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
@ -13,6 +13,7 @@ import static org.mockito.Mockito.when;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
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.testing.assertj.OpenTelemetryAssertions;
@ -42,7 +43,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaStreamWrapperTest$TestRequestHandler::handleRequest")
"io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaStreamWrapperTest$TestRequestHandler::handleRequest")
public class AwsLambdaStreamWrapperTest {
@RegisterExtension

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

View File

@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import com.amazonaws.services.lambda.runtime.Context;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
class LambdaParametersTest {
public void onlyContext(Context context) {}
public void contextOnThird(String one, String two, Context context) {}
@Test
void shouldSetContextOnFirstPosition() throws NoSuchMethodException {
// given
Context context = mock(Context.class);
Method method = getClass().getMethod("onlyContext", Context.class);
// when
Object[] params = LambdaParameters.toArray(method, "", context);
// then
assertThat(params).hasSize(1);
assertThat(params[0]).isEqualTo(context);
}
@Test
void shouldSetContextOnTheLastPosition() throws NoSuchMethodException {
// given
Context context = mock(Context.class);
Method method =
getClass().getMethod("contextOnThird", String.class, String.class, Context.class);
// when
Object[] params = LambdaParameters.toArray(method, "", context);
// then
assertThat(params).hasSize(3);
assertThat(params[0]).isEqualTo("");
assertThat(params[1]).isNull();
assertThat(params[2]).isEqualTo(context);
}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@ -11,14 +11,12 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.extension.aws.AwsXrayPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.jupiter.api.BeforeEach;
@ -72,7 +70,7 @@ class ApiGatewayProxyRequestTest {
}
@Test
public void shouldUseCopyIfMarkingNotAvailableAndHttpPropagatorsSet() throws IOException {
public void shouldUseNoopIfMarkingNotAvailableAndHttpPropagatorsSet() throws IOException {
// given
InputStream mock = mock(InputStream.class);
given(mock.markSupported()).willReturn(false);
@ -82,9 +80,7 @@ class ApiGatewayProxyRequestTest {
// when
ApiGatewayProxyRequest created = ApiGatewayProxyRequest.forStream(mock);
// then
assertThat(created.freshStream()).isInstanceOf(ByteArrayInputStream.class);
then(mock).should(never()).mark(any(Integer.class));
then(mock).should(never()).reset();
then(mock).should().read(any());
assertThat(created.freshStream()).isEqualTo(mock);
assertThat(created.getHeaders()).isEmpty();
}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
@ -46,6 +46,6 @@ class HeadersFactoryTest {
InputStream inputStream = new ByteArrayInputStream(json.getBytes(Charset.defaultCharset()));
// when
Map<String, String> headers = HeadersFactory.ofStream(inputStream); // then
assertThat(headers).isNull();
assertThat(headers).isEmpty();
}
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -0,0 +1,19 @@
plugins {
id("otel.java-conventions")
}
dependencies {
api(project(":testing-common"))
api("com.amazonaws:aws-lambda-java-core:1.0.0")
api("org.junit-pioneer:junit-pioneer")
api("org.mockito:mockito-junit-jupiter")
implementation("com.google.guava:guava")
implementation("org.codehaus.groovy:groovy-all")
implementation("io.opentelemetry:opentelemetry-api")
implementation("org.spockframework:spock-core")
implementation("com.github.stefanbirkner:system-lambda")
}

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdacore.v1_0;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

View File

@ -13,7 +13,12 @@ muzzle {
}
dependencies {
implementation(project(":instrumentation:aws-lambda-1.0:library"))
implementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
implementation(project(":instrumentation:aws-lambda:aws-lambda-events-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")
}
library("com.amazonaws:aws-lambda-java-core:1.0.0")
// First version to includes support for SQSEvent, currently the most popular message queue used
@ -22,5 +27,6 @@ dependencies {
// in public API.
library("com.amazonaws:aws-lambda-java-events:2.2.1")
testImplementation(project(":instrumentation:aws-lambda-1.0:testing"))
testImplementation(project(":instrumentation:aws-lambda:aws-lambda-events-2.2:testing"))
testInstrumentation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:javaagent"))
}

View File

@ -0,0 +1,35 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaEventsInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
public final class AwsLambdaInstrumentationHelper {
private static final io.opentelemetry.instrumentation.awslambdacore.v1_0.internal
.AwsLambdaFunctionInstrumenter
FUNCTION_INSTRUMENTER =
AwsLambdaEventsInstrumenterFactory.createInstrumenter(GlobalOpenTelemetry.get());
public static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal
.AwsLambdaFunctionInstrumenter
functionInstrumenter() {
return FUNCTION_INSTRUMENTER;
}
private static final Instrumenter<SQSEvent, Void> MESSAGE_TRACER =
AwsLambdaSqsInstrumenterFactory.forEvent(GlobalOpenTelemetry.get());
public static Instrumenter<SQSEvent, Void> messageInstrumenter() {
return MESSAGE_TRACER;
}
private AwsLambdaInstrumentationHelper() {}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambdaevents.v2_2;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static java.util.Collections.singletonList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public class AwsLambdaInstrumentationModule extends InstrumentationModule {
public AwsLambdaInstrumentationModule() {
super("aws-lambda", "aws-lambda-events-2.2");
}
@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
return hasClassesNamed("com.amazonaws.services.lambda.runtime.events.SQSEvent");
}
@Override
public boolean isHelperClass(String className) {
return className.startsWith("io.opentelemetry.extension.aws.");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new AwsLambdaRequestHandlerInstrumentation());
}
}

View File

@ -3,12 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambda.v1_0;
package io.opentelemetry.javaagent.instrumentation.awslambdaevents.v2_2;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.instrumentation.awslambda.v1_0.AwsLambdaInstrumentationHelper.functionInstrumenter;
import static io.opentelemetry.javaagent.instrumentation.awslambda.v1_0.AwsLambdaInstrumentationHelper.messageInstrumenter;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
@ -17,7 +15,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.api.OpenTelemetrySdkAccess;
@ -63,18 +61,24 @@ public class AwsLambdaRequestHandlerInstrumentation implements TypeInstrumentati
@Advice.Local("otelMessageContext") io.opentelemetry.context.Context messageContext,
@Advice.Local("otelMessageScope") Scope messageScope) {
input = AwsLambdaRequest.create(context, arg, Collections.emptyMap());
io.opentelemetry.context.Context parentContext = functionInstrumenter().extract(input);
io.opentelemetry.context.Context parentContext =
AwsLambdaInstrumentationHelper.functionInstrumenter().extract(input);
if (!functionInstrumenter().shouldStart(parentContext, input)) {
if (!AwsLambdaInstrumentationHelper.functionInstrumenter()
.shouldStart(parentContext, input)) {
return;
}
functionContext = functionInstrumenter().start(parentContext, input);
functionContext =
AwsLambdaInstrumentationHelper.functionInstrumenter().start(parentContext, input);
functionScope = functionContext.makeCurrent();
if (arg instanceof SQSEvent) {
if (messageInstrumenter().shouldStart(functionContext, (SQSEvent) arg)) {
messageContext = messageInstrumenter().start(functionContext, (SQSEvent) arg);
if (AwsLambdaInstrumentationHelper.messageInstrumenter()
.shouldStart(functionContext, (SQSEvent) arg)) {
messageContext =
AwsLambdaInstrumentationHelper.messageInstrumenter()
.start(functionContext, (SQSEvent) arg);
messageScope = messageContext.makeCurrent();
}
}
@ -92,12 +96,14 @@ public class AwsLambdaRequestHandlerInstrumentation implements TypeInstrumentati
if (messageScope != null) {
messageScope.close();
messageInstrumenter().end(messageContext, (SQSEvent) arg, null, throwable);
AwsLambdaInstrumentationHelper.messageInstrumenter()
.end(messageContext, (SQSEvent) arg, null, throwable);
}
if (functionScope != null) {
functionScope.close();
functionInstrumenter().end(functionContext, input, null, throwable);
AwsLambdaInstrumentationHelper.functionInstrumenter()
.end(functionContext, input, null, throwable);
}
OpenTelemetrySdkAccess.forceFlush(1, TimeUnit.SECONDS);

View File

@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.awslambda.v1_0;
package io.opentelemetry.javaagent.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.instrumentation.awslambda.v1_0.AbstractAwsLambdaSqsEventHandlerTest;
import io.opentelemetry.instrumentation.awslambdaevents.v2_2.AbstractAwsLambdaSqsEventHandlerTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

View File

@ -9,9 +9,12 @@ and use one of wrappers as your lambda `Handler`.
In order to configure a span flush timeout (default is set to 1 second), please configure `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` env property. The value is in seconds.
Available wrappers:
- `io.opentelemetry.instrumentation.awslambda.v1_0.TracingRequestWrapper` - for wrapping regular handlers (implementing `RequestHandler`)
- `io.opentelemetry.instrumentation.awslambda.v1_0.TracingRequestApiGatewayWrapper` - for wrapping regular handlers (implementing `RequestHandler`) proxied through API Gateway, enabling HTTP context propagation
- `io.opentelemetry.instrumentation.awslambda.v1_0.TracingRequestStreamWrapper` - for wrapping streaming handlers (implementing `RequestStreamHandler`), enabling HTTP context propagation for HTTP requests
- `io.opentelemetry.instrumentation.awslambdaevents.v2_2.TracingRequestWrapper` - for wrapping regular handlers (implementing `RequestHandler`)
- `io.opentelemetry.instrumentation.awslambdaevents.v2_2.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

View File

@ -3,6 +3,8 @@ plugins {
}
dependencies {
api(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:library"))
compileOnly("io.opentelemetry:opentelemetry-sdk")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
@ -16,10 +18,11 @@ dependencies {
// in public API.
library("com.amazonaws:aws-lambda-java-events:2.2.1")
compileOnly("com.fasterxml.jackson.core:jackson-databind")
compileOnly("commons-io:commons-io:2.2")
compileOnly("org.slf4j:slf4j-api")
// 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(anuraaga): Switch to aws-lambda-java-serialization to more robustly follow Lambda's serialization logic.
implementation("com.fasterxml.jackson.core:jackson-databind")
implementation("io.opentelemetry:opentelemetry-extension-aws")
// allows to get the function ARN
@ -27,14 +30,11 @@ dependencies {
// allows to get the default events
testLibrary("com.amazonaws:aws-lambda-java-events:3.10.0")
testImplementation("com.fasterxml.jackson.core:jackson-databind")
testImplementation("commons-io:commons-io:2.2")
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
testImplementation("com.google.guava:guava")
testImplementation(project(":instrumentation:aws-lambda-1.0:testing"))
testImplementation(project(":instrumentation:aws-lambda:aws-lambda-events-2.2:testing"))
testImplementation("org.mockito:mockito-core")
testImplementation("org.assertj:assertj-core")
testImplementation("uk.org.webcompere:system-stubs-jupiter")

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import java.lang.reflect.Method;

View File

@ -3,18 +3,20 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.util.function.BiFunction;
/**
* Wrapper for {@link TracingRequestHandler}. Allows for wrapping a lambda proxied through API
* Gateway, enabling single span tracing and HTTP context propagation.
* 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<APIGatewayProxyRequestEvent, Object> {

View File

@ -3,14 +3,16 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.util.function.BiFunction;
/**
* Wrapper for {@link TracingRequestHandler}. Allows for wrapping a regular lambda, not proxied
* through API Gateway. Therefore, HTTP headers propagation is not supported.
* Wrapper for {@link io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler}.
* Allows for wrapping a regular lambda, not proxied through API Gateway. Therefore, HTTP headers
* propagation is not supported.
*/
public class TracingRequestWrapper extends TracingRequestWrapperBase<Object, Object> {
public TracingRequestWrapper() {

View File

@ -3,15 +3,23 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
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.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;
/**
@ -40,7 +48,10 @@ abstract class TracingRequestWrapperBase<I, O> extends TracingRequestHandler<I,
OpenTelemetrySdk openTelemetrySdk,
WrappedLambda wrappedLambda,
BiFunction<I, Class<?>, Object> parameterMapper) {
super(openTelemetrySdk, WrapperConfiguration.flushTimeout());
super(
openTelemetrySdk,
WrapperConfiguration.flushTimeout(),
AwsLambdaEventsInstrumenterFactory.createInstrumenter(openTelemetrySdk));
this.wrappedLambda = wrappedLambda;
this.targetMethod = wrappedLambda.getRequestTargetMethod();
this.parameterMapper = parameterMapper;
@ -62,4 +73,12 @@ abstract class TracingRequestWrapperBase<I, O> extends TracingRequestHandler<I,
}
return result;
}
@Override
protected final Map<String, String> extractHttpHeaders(I input) {
if (input instanceof APIGatewayProxyRequestEvent) {
return MapUtils.emptyIfNull(((APIGatewayProxyRequestEvent) input).getHeaders());
}
return Collections.emptyMap();
}
}

View File

@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaFunctionInstrumenter;
import io.opentelemetry.instrumentation.awslambda.v1_0.internal.AwsLambdaSqsInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler;
import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.time.Duration;
@ -39,7 +39,8 @@ public abstract class TracingSqsEventHandler extends TracingRequestHandler<SQSEv
/**
* 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 AwsLambdaFunctionInstrumenter}.
* invocation, and traces using the provided {@link
* io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter}.
*/
protected TracingSqsEventHandler(
OpenTelemetrySdk openTelemetrySdk,

View File

@ -3,10 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
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.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import java.lang.reflect.InvocationTargetException;

View File

@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
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.awslambda.v1_0.internal.AwsLambdaSqsInstrumenterFactory;
import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.AwsLambdaSqsInstrumenterFactory;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.time.Duration;

View File

@ -3,10 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import static io.opentelemetry.instrumentation.awslambda.v1_0.internal.MapUtils.emptyIfNull;
import static io.opentelemetry.instrumentation.awslambda.v1_0.internal.MapUtils.lowercaseMap;
import static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils.emptyIfNull;
import static io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils.lowercaseMap;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.FAAS_TRIGGER;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_METHOD;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_STATUS_CODE;
@ -18,7 +18,7 @@ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

View File

@ -3,19 +3,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionAttributesExtractor;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.AwsLambdaFunctionInstrumenter;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public class AwsLambdaFunctionInstrumenterFactory {
public class AwsLambdaEventsInstrumenterFactory {
public static AwsLambdaFunctionInstrumenter createInstrumenter(OpenTelemetry openTelemetry) {
return new AwsLambdaFunctionInstrumenter(
@ -23,7 +25,7 @@ public class AwsLambdaFunctionInstrumenterFactory {
Instrumenter.builder(
openTelemetry,
"io.opentelemetry.aws-lambda-1.0",
AwsLambdaFunctionInstrumenterFactory::spanName)
AwsLambdaEventsInstrumenterFactory::spanName)
.addAttributesExtractors(
new AwsLambdaFunctionAttributesExtractor(),
new ApiGatewayProxyAttributesExtractor())

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.api.common.AttributesBuilder;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import io.opentelemetry.context.Context;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
import io.opentelemetry.api.common.AttributesBuilder;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0.internal;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
import io.opentelemetry.api.trace.Span;
@ -11,6 +11,7 @@ import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.SpanLinksBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanLinksExtractor;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.ParentContextExtractor;
class SqsMessageSpanLinksExtractor implements SpanLinksExtractor<SQSMessage> {
private static final String AWS_TRACE_HEADER_SQS_ATTRIBUTE_KEY = "AWSTraceHeader";

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
@ -14,6 +14,7 @@ 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.sdk.testing.assertj.OpenTelemetryAssertions;
@ -58,7 +59,7 @@ public class AwsLambdaApiGatewayWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
void tracedWithHttpPropagation() {
TracingRequestApiGatewayWrapper wrapper =
new TracingRequestApiGatewayWrapper(
@ -117,7 +118,7 @@ public class AwsLambdaApiGatewayWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerApiGateway::handleRequest")
void handlerTraced_empty() {
TracingRequestApiGatewayWrapper wrapper =
new TracingRequestApiGatewayWrapper(
@ -151,7 +152,7 @@ public class AwsLambdaApiGatewayWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerString::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerString::handleRequest")
void handlerTraced_string() {
TracingRequestApiGatewayWrapper wrapper =
new TracingRequestApiGatewayWrapper(
@ -185,7 +186,7 @@ public class AwsLambdaApiGatewayWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerInteger::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerInteger::handleRequest")
void handlerTraced_integer() {
TracingRequestApiGatewayWrapper wrapper =
new TracingRequestApiGatewayWrapper(
@ -219,7 +220,7 @@ public class AwsLambdaApiGatewayWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerCustomType::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaApiGatewayWrapperTest$TestRequestHandlerCustomType::handleRequest")
void handlerTraced_customType() {
TracingRequestApiGatewayWrapper wrapper =
new TracingRequestApiGatewayWrapper(

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
@ -13,6 +13,7 @@ import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
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.resource.attributes.ResourceAttributes;
@ -32,7 +33,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaSqsEventWrapperTest$TestRequestHandler::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaSqsEventWrapperTest$TestRequestHandler::handleRequest")
public class AwsLambdaSqsEventWrapperTest {
@RegisterExtension

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
@ -13,6 +13,7 @@ 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.testing.assertj.OpenTelemetryAssertions;
@ -53,7 +54,7 @@ public class AwsLambdaWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
void handlerTraced() {
TracingRequestWrapper wrapper =
new TracingRequestWrapper(
@ -84,7 +85,7 @@ public class AwsLambdaWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaWrapperTest$TestRequestHandlerString::handleRequest")
void handlerTracedWithException() {
TracingRequestWrapper wrapper =
new TracingRequestWrapper(
@ -117,7 +118,7 @@ public class AwsLambdaWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaWrapperTest$TestRequestHandlerInteger::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaWrapperTest$TestRequestHandlerInteger::handleRequest")
void handlerTraced_integer() {
TracingRequestWrapper wrapper =
new TracingRequestWrapper(
@ -148,7 +149,7 @@ public class AwsLambdaWrapperTest {
@SetEnvironmentVariable(
key = WrappedLambda.OTEL_LAMBDA_HANDLER_ENV_KEY,
value =
"io.opentelemetry.instrumentation.awslambda.v1_0.AwsLambdaWrapperTest$TestRequestHandlerCustomType::handleRequest")
"io.opentelemetry.instrumentation.awslambdaevents.v2_2.AwsLambdaWrapperTest$TestRequestHandlerCustomType::handleRequest")
void handlerTraced_custom() {
TracingRequestWrapper wrapper =
new TracingRequestWrapper(

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
@ -17,6 +17,7 @@ import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.util.HashMap;
import java.util.Map;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.awslambda.v1_0;
package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.entry;

View File

@ -135,9 +135,12 @@ include(":instrumentation:armeria-1.3:library")
include(":instrumentation:armeria-1.3:testing")
include(":instrumentation:async-http-client:async-http-client-1.9:javaagent")
include(":instrumentation:async-http-client:async-http-client-2.0:javaagent")
include(":instrumentation:aws-lambda-1.0:javaagent")
include(":instrumentation:aws-lambda-1.0:library")
include(":instrumentation:aws-lambda-1.0:testing")
include(":instrumentation:aws-lambda:aws-lambda-core-1.0:javaagent")
include(":instrumentation:aws-lambda:aws-lambda-core-1.0:library")
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-sdk:aws-sdk-1.11:javaagent")
include(":instrumentation:aws-sdk:aws-sdk-1.11:javaagent-unit-tests")
include(":instrumentation:aws-sdk:aws-sdk-1.11:library")