AWS X-Ray seems like a potentially useful yet undervalued AWS service. It is supposed to simplify the debugging and analysis of cloud-based applications providing a complete view of various requests traveling through your app and filtering the visual data for better comprehension. 

Let’s test it out with a simple use case – I decided to pick out a typical serverless REST API using: 

  • API Gateway, 
  • Amazon Lambda, 
  • and DynamoDB

The primary purpose of this test was to see if the AWS X-Ray tool would be more useful when debugging such an application compared to just sifting through Cloudwatch logs.

In the example, I have an API Gateway endpoint that reads some arbitrary data from a DynamoDB table called ‘xray-users-table’ and saves some to another - ‘xray-transactions-table’.

Here’s the code of the Node.js Lambda that I created:

const { 
   DynamoDBClient, 
   PutItemCommand, 
   GetItemCommand 
} = require('@aws-sdk/client-dynamodb')
const AWSXRay = require('aws-xray-sdk')
const { v4: uuidv4 } = require('uuid')

const dbclient = AWSXRay.captureAWSv3Client(
  new DynamoDBClient({ region: 'eu-central-1' })
)

exports.handler = async event =>{
  const { user_id } = JSON.parse(event.body)
  let user
  try {
    user = await dbclient.send(
      new GetItemCommand({
        TableName: 'xray-users-table',
        Key: {
          user_id: { S: user_id },
        },
      })
    )
  } catch (e) {
    console.error(e)
    return {
      statusCode: 400,
      body: JSON.stringify({ msg: 'Could not find user' }),
    }
  }

  const transaction_id = uuidv4()
  try {
    dbclient.send(
      new PutItemCommand({
        TableName: 'xray-transactions-table',
        Item: {
          transaction_id: { S: `${transaction_id}`},
          user_id: { S: user_id },
          user_data: { S: user.Item.data.S },
        },
      })
    )
  } catch (e) {
    console.error(e)
    return {
      statusCode: 500,
      body: JSON.stringify({ msg: 'Could not save transaction' }),
    }
  }

  return {
    statusCode: 201,
    body: JSON.stringify({msg: `Transaction saved with id ${transaction_id}`}),
  }
}

Enabling the X-Ray on such a setup turned out to be more than one click, but nothing of particular difficulty either. I had to turn it on in each of the services involved, with some caveats (which are explained in the video). Once you know how to do it, setting it up is not a big problem at all.

After enabling the tracing on all of the services, I ran a few both successful and unsuccessful requests to generate some traces to then find out what I could learn about them from the X-Ray dashboard, and what I found out was really pleasant. I could see each request as it passed through the components of the API.

I could filter and sort the requests by various criteria - most interesting to me, by HTTP status codes. While this may not be the most robust tracing solution out there, it’s quick to enable, doesn’t cost anything, and can give you some really valuable insight into how your app works or help you localize which of the services caused a request to not go through.

I encourage you to watch the video to learn more and try X-Ray by yourself in your projects. It’s a nifty tool that easy to integrate and free to use, and it might just save you some tedious browsing through these CloudWatch logs.

Watch the video above for all tips and tricks on conducting serverless tracing with AWS X-Ray.

Want to learn more from professional backend developers? Check out the other blog post from our Feel The Tech series.