Documentation forAppOptics

Serverless

The AppOptics Java agent provides an instrumentation SDK for AWS Lambda as the appoptics-aws-lambda Maven artifact, which provides a convenience wrapper to trace functions, wrappers to propagate the trace context in Apache Http clients, and OpenTelemetry-compatible SDK to create custom spans for additional insight. In addition, appoptics-aws-lambda supports code profiling when the function is configured with enough memory/CPU. Ensure that prerequisites described in tracing are set up before proceeding.

Instrumentation

The instructions to enable instrumentation on a Java AWS Lambda function depend on whether or not your function has already implemented com.amazonaws.services.lambda.runtime.RequestHandler or com.amazonaws.services.lambda.runtime.RequestStreamHandler.

Option 1: com.amazonaws.services.lambda.runtime.RequestHandler or com.amazonaws.services.lambda.runtime.RequestStreamHandler has already been implemented by your function.

  1. Add the dependency com.appoptics.agent.java:appoptics-aws-lambda to your project
  2. Implement com.appoptics.awslambda.handler.TracedRequestHandler/com.appoptics.awslambda.handler.TracedRequestStreamHandler instead of com.amazonaws.services.lambda.runtime.RequestHandler/com.amazonaws.services.lambda.runtime.RequestStreamHandler
  3. Rename the method handleRequest to doHandleRequest
  4. Redeploy the AWS Lambda function.

Code example:

Copy
import com.appoptics.awslambda.handler.TracedRequestHandler;

public class MyHandler implements TracedRequestHandler<APIGatewayV2ProxyRequestEvent, APIGatewayV2ProxyResponseEvent> { //replaced RequestHandler with TracedRequestHandler
  
  @Override
  public APIGatewayV2ProxyResponseEvent doHandleRequest(APIGatewayV2ProxyRequestEvent input, Context context) { //renamed from handleRequest
    //...
  }
}

Option 2: com.amazonaws.services.lambda.runtime.RequestHandler or com.amazonaws.services.lambda.runtime.RequestStreamHandler is not implemented by your function.

  1. Add the dependency com.appoptics.agent.java:appoptics-aws-lambda to your project
  2. Wrap the existing code logic with method instrument or instrumentChecked of com.appoptics.awslambda.handler.HandlerInstrumentor
  3. Redeploy the AWS Lambda function

Code example:

Copy
import com.appoptics.awslambda.handler.HandlerInstrumentor;

public class MyHandler {
  
public Output myMethod(Input input, Context context) throws IOException { //method signature unchanged
  return HandlerInstrumentor.instrumentChecked(input, context, getClass(), () -> {
    // original code logic that might throw IOException...
  }
}

Our instrumentation automatically captures the duration and various AWS Lambda specific information for the function invoked. Code profiling is enabled when the function is configured with memory size greater than or equal to 512 MB.

The complete javadoc is available at https://librato.github.io/java-aws-lambda-javadoc/

For instrumentation of outbound Apache HTTP client calls, replace usage of org.apache.http.impl.client.HttpClientBuilder with our com.appoptics.awslambda.wrapper.httpclient.apache.HttpClientBuilder. Alternatively, for older versions replace usage of org.apache.http.impl.client.DefaultHttpClient with our com.appoptics.awslambda.wrapper.httpclient.apache.DefaultHttpClient.

Configuration

Below configuration options for AWS Lambda are available and can be set as Lambda function environment variables. See Using AWS Lambda environment variables in the Amazon Web Services documentation for more information about environment variables.

  • APPOPTICS_AGENT_ENABLED - enabled by default; set to false to disable instrumentation.
  • APPOPTICS_LOGGING - used to turn on more verbose logging for diagnostics. Default is info, see Logging Level for details related to configuring logging levels.
  • APPOPTICS_TRANSACTION_NAME - a custom transaction name for the trace; used in place of the default.
  • APPOPTICS_PROFILER_ENABLED - set to true or false to explicitly enable or disable profiling. By default, profiling will be enabled only for AWS Lambda functions with >= 512 MB allocated memory
  • APPOPTICS_PROFILER_INTERVAL - set the profiler interval in ms. By default the profiler polls the JVM every 20 ms to obtain snapshots to build performance profiles. Lower interval value gives more granular profiling data but imposes more overhead. The value should be >= 10.

Troubleshooting

Enable debug logging for the agent by setting the environment variable APPOPTICS_LOGGING=debug.

You may not want to enable debug logging in the production environment as it may produce an excessive amount of logs.

Cannot see any trace data

Ensure that prerequisites described in tracing are set up and check for trace data in the CloudWatch Logs log group for your Lambda function.

You can also look for the following message in CloudWatch Logs, which indicates that the agent is enabled and working:

Oct 09, 2020 11:24:58.210 PM INFO [AppOptics] AppOptics AWS Lambda version [1.0.0] : Initialized Lambda tracer! Detailed tracing: true profiling: true metric: true

Missing traces on some requests

Only request handlers that implement com.appoptics.awslambda.handler.TracedRequestHandler, com.appoptics.awslambda.handler.TracedRequestStreamHandler, or use the methods provided in com.appoptics.agent.java:appoptics-aws-lambda.HandlerInstrumentor will be instrumented.

Traces are subjected to rate limits, therefore on a burst of request volume some requests may not be traced.

Missing profiling information

Code profiling is enabled only for functions with >= 512 MB allocated memory. To enable code profiling for functions with less memory, set the environment variable APPOPTICS_PROFILER_ENABLED=true.

There is a circuit breaker mechanism that pauses code profiling if the system is under heavy load. For code profiling status, check the value of the ProfilerStatus KV on the root span of the trace for details.

Instrumentation triggers unexpected exceptions

Any unexpected exception will be logged to the function’s CloudWatch Logs and should not affect normal AWS Lambda function execution in most cases.

Uninstall

Revert any code changes made to remove the AWS Lambda wrapper. Alternatively, you can define the eenvironment variable APPOPTIC_AGENT_ENABLED=false to disable the agent temporarily instead.