From 179b2257f9c56446c423aa1646fefad254aa8bde Mon Sep 17 00:00:00 2001 From: Jakub Wach Date: Mon, 11 Jan 2021 19:50:00 +0100 Subject: [PATCH] AWS lambda - configurable flush timeout (#1960) --- .../aws-lambda-1.0/library/README.md | 4 ++- .../awslambda/v1_0/TracingRequestHandler.java | 16 ++++++++++- .../v1_0/TracingRequestStreamHandler.java | 19 ++++++++++++- .../v1_0/TracingRequestStreamWrapper.java | 10 ++++--- .../v1_0/TracingRequestWrapperBase.java | 6 ++++- .../awslambda/v1_0/WrappedLambda.java | 3 ++- .../awslambda/v1_0/WrapperConfiguration.java | 27 +++++++++++++++++++ 7 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrapperConfiguration.java diff --git a/instrumentation/aws-lambda-1.0/library/README.md b/instrumentation/aws-lambda-1.0/library/README.md index a3d0da16509d..9147aa297557 100644 --- a/instrumentation/aws-lambda-1.0/library/README.md +++ b/instrumentation/aws-lambda-1.0/library/README.md @@ -3,9 +3,11 @@ This package contains libraries to help instrument AWS lambda functions in your code. ## Using wrappers -To use the instrumentation, configure `OTEL_LAMBDA_HANDLER` env property to your lambda handler method in following format `package.ClassName::methodName` +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.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 diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestHandler.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestHandler.java index 8fe2f5563880..d54426b64588 100644 --- a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestHandler.java +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestHandler.java @@ -24,11 +24,21 @@ */ public abstract class TracingRequestHandler implements RequestHandler { + private static final long DEFAULT_FLUSH_TIMEOUT_SECONDS = 1; + private final AwsLambdaTracer tracer; + private final long flushTimeout; + + /** Creates a new {@link TracingRequestHandler} which traces using the default {@link Tracer}. */ + protected TracingRequestHandler(long flushTimeout) { + this.tracer = new AwsLambdaTracer(); + this.flushTimeout = flushTimeout; + } /** Creates a new {@link TracingRequestHandler} which traces using the default {@link Tracer}. */ protected TracingRequestHandler() { this.tracer = new AwsLambdaTracer(); + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } /** @@ -36,6 +46,7 @@ protected TracingRequestHandler() { */ protected TracingRequestHandler(Tracer tracer) { this.tracer = new AwsLambdaTracer(tracer); + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } /** @@ -44,6 +55,7 @@ protected TracingRequestHandler(Tracer tracer) { */ protected TracingRequestHandler(AwsLambdaTracer tracer) { this.tracer = tracer; + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } private Map getHeaders(I input) { @@ -71,7 +83,9 @@ public final O handleRequest(I input, Context context) { } else { tracer.end(span); } - OpenTelemetrySdk.getGlobalTracerManagement().forceFlush().join(1, TimeUnit.SECONDS); + OpenTelemetrySdk.getGlobalTracerManagement() + .forceFlush() + .join(flushTimeout, TimeUnit.SECONDS); } } diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamHandler.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamHandler.java index e06037cc00b6..4b09da897498 100644 --- a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamHandler.java +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamHandler.java @@ -23,7 +23,19 @@ */ public abstract class TracingRequestStreamHandler implements RequestStreamHandler { + private static final long DEFAULT_FLUSH_TIMEOUT_SECONDS = 1; + private final AwsLambdaTracer tracer; + private final long flushTimeout; + + /** + * Creates a new {@link TracingRequestStreamHandler} which traces using the default {@link + * Tracer}. + */ + protected TracingRequestStreamHandler(long flushTimeout) { + this.tracer = new AwsLambdaTracer(); + this.flushTimeout = flushTimeout; + } /** * Creates a new {@link TracingRequestStreamHandler} which traces using the default {@link @@ -31,6 +43,7 @@ public abstract class TracingRequestStreamHandler implements RequestStreamHandle */ protected TracingRequestStreamHandler() { this.tracer = new AwsLambdaTracer(); + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } /** @@ -39,6 +52,7 @@ protected TracingRequestStreamHandler() { */ protected TracingRequestStreamHandler(Tracer tracer) { this.tracer = new AwsLambdaTracer(tracer); + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } /** @@ -47,6 +61,7 @@ protected TracingRequestStreamHandler(Tracer tracer) { */ protected TracingRequestStreamHandler(AwsLambdaTracer tracer) { this.tracer = tracer; + this.flushTimeout = DEFAULT_FLUSH_TIMEOUT_SECONDS; } @Override @@ -60,7 +75,9 @@ public void handleRequest(InputStream input, OutputStream output, Context contex doHandleRequest(proxyRequest.freshStream(), new OutputStreamWrapper(output, span), context); } catch (Throwable t) { tracer.endExceptionally(span, t); - OpenTelemetrySdk.getGlobalTracerManagement().forceFlush().join(1, TimeUnit.SECONDS); + OpenTelemetrySdk.getGlobalTracerManagement() + .forceFlush() + .join(flushTimeout, TimeUnit.SECONDS); throw t; } } diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamWrapper.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamWrapper.java index e44d26e144a4..63e9d020063a 100644 --- a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamWrapper.java +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestStreamWrapper.java @@ -13,15 +13,19 @@ /** * Wrapper for {@link TracingRequestStreamHandler}. Allows for wrapping a regular lambda, enabling - * single span tracing. Main lambda class should be configured as env property OTEL_LAMBDA_HANDLER - * in package.ClassName::methodName format. Lambda class must implement {@link - * RequestStreamHandler}. + * single span tracing. Main lambda class should be configured as env property + * OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER in package.ClassName::methodName format. Lambda class + * must implement {@link RequestStreamHandler}. */ public class TracingRequestStreamWrapper extends TracingRequestStreamHandler { // visible for testing static WrappedLambda WRAPPED_LAMBDA = WrappedLambda.fromConfiguration(); + public TracingRequestStreamWrapper() { + super(WrapperConfiguration.flushTimeout()); + } + @Override protected void doHandleRequest(InputStream inputStream, OutputStream output, Context context) throws IOException { diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestWrapperBase.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestWrapperBase.java index b49ce201cb88..ae783687b9d0 100644 --- a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestWrapperBase.java +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/TracingRequestWrapperBase.java @@ -11,10 +11,14 @@ /** * Base abstract wrapper for {@link TracingRequestHandler}. Provides: - delegation to a lambda via - * env property OTEL_LAMBDA_HANDLER in package.ClassName::methodName format + * env property OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER in package.ClassName::methodName format */ abstract class TracingRequestWrapperBase extends TracingRequestHandler { + protected TracingRequestWrapperBase() { + super(WrapperConfiguration.flushTimeout()); + } + // visible for testing static WrappedLambda WRAPPED_LAMBDA = WrappedLambda.fromConfiguration(); diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrappedLambda.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrappedLambda.java index 902942dc53f9..5655cecc8786 100644 --- a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrappedLambda.java +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrappedLambda.java @@ -17,7 +17,8 @@ /** Model for wrapped lambda function (object, class, method). */ class WrappedLambda { - public static final String OTEL_LAMBDA_HANDLER_ENV_KEY = "OTEL_LAMBDA_HANDLER"; + public static final String OTEL_LAMBDA_HANDLER_ENV_KEY = + "OTEL_INSTRUMENTATION_AWS_LAMBDA_HANDLER"; private final Object targetObject; private final Class targetClass; diff --git a/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrapperConfiguration.java b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrapperConfiguration.java new file mode 100644 index 000000000000..79a075057c94 --- /dev/null +++ b/instrumentation/aws-lambda-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambda/v1_0/WrapperConfiguration.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.awslambda.v1_0; + +public final class WrapperConfiguration { + + private WrapperConfiguration() {} + + public static final String OTEL_LAMBDA_FLUSH_TIMEOUT_ENV_KEY = + "OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT"; + public static final long OTEL_LAMBDA_FLUSH_TIMEOUT_DEFAULT = 1; + + public static final long flushTimeout() { + String lambdaFlushTimeout = System.getenv(OTEL_LAMBDA_FLUSH_TIMEOUT_ENV_KEY); + if (lambdaFlushTimeout != null && !lambdaFlushTimeout.isEmpty()) { + try { + return Long.parseLong(lambdaFlushTimeout); + } catch (NumberFormatException nfe) { + // ignored - default used + } + } + return OTEL_LAMBDA_FLUSH_TIMEOUT_DEFAULT; + } +}