Tracing Java based Lambda using X-Ray and AWS PowerTools
Tracing makes it very easy to identify and debug issues with your application. Especially issues related to performance can be identified easily as tracing lets you dig deep into component level activity.
HTTP endpoints backed by AWS Lambdas can be monitored using AWS X-Ray for the same purpose. We will make use of powertools-tracking
library to configure tracing in our Lambda. The library and the corresponding documentation can be found at https://awslabs.github.io/aws-lambda-powertools-java/core/tracing/
Additionally, the sample project I am using is built using Serverless Framework (https://www.serverless.com/framework), so this blog post will not contain any examples related to Cloudformation configuration. Cloudformation templates are created and managed by Serverless Framework.
We will start by adding the following plugins and dependencies to build.gradle (or maven if maven is your dependency manager)
plugins {
id 'io.freefair.aspectj.post-compile-weaving' version '6.3.0'
...
}
dependencies {
aspect 'software.amazon.lambda:powertools-tracing:1.10.0'
...
}
In serverless.yml
, tracing must be enabled by adding the following properties.
provider:
name: aws
...
tracing:
lambda: true
apiGateway: true
This configuration will add the necessary configuration to the Cloudformation template which is finally applied against AWS to create the Lambda stack.
As a final step, all the necessary Lambda handlers must be annotated with @Tracing
to enable tracing.
public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Tracing
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
businessLogic1();
businessLogic2();
}
That is all that is needed. You should be able to see traces in X-Ray once deployed. An additional benefit of deploying X-Ray tracing for lambda with API Gateway in front is that we can monitor the cold start time of the Lambda and use that data to do necessary changes.
Instrumenting SDK clients and HTTP calls
Calls made to other HTTP endpoints and AWS services using the AWS SDK can be instrumented to capture the time taken by those corresponding services.
All AWS SDK Services let you configure a Tracing handler which shares the same span details as the Lambda with the underlying AWS SDK calls. This will show the SDK call timings within our lambda operation in X-Ray. Following is an example from the documentation at https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-awssdkclients.html
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.handlers.TracingHandler;
...
public class MyModel {
private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().withRegion(Regions.fromName(System.getenv("AWS\_REGION")))`**.withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))**`.build();
...
}
Similarly Apache HTTP client can be instrumented by following the documentation at https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-httpclients.html