Go back you your Cloud9 environment and open your app workspace at serverless-observability-workshop/code/sample-app-tracing.
Lambda doesn’t allow us to add custom annotations and metadata to its root segment, so we first need to create our custom subsegment by updating our handler.
Edit the serverless-observability-workshop/code/sample-app-tracing/src/handlers/get-all-items.js file to add an initial subsegment called ## Handler using the AWSXRay.captureAsyncFunc() method on the entire handler method and closing the subsegment inside a new finally clause in our try/catch.
exports.getAllItemsHandler = async (event, context) => {
return AWSXRay.captureAsyncFunc('## Handler', async (subsegment) => {
// Initialization
try{
// Happy Path
} catch(err) {
// Exception Handling
} finally {
subsegment.close()
}
return response
}, AWSXRay.getSegment());
}
Next, we are ready to add our annotations in case of successful and failed executions to our given Item ID. Inside your handler, find and add in the end of your try and beginning of your catch statements the annotations for ItemsCount and Status:
// Initialization
try{
// Happy Path
//Tracing
subsegment.addAnnotation('ItemsCount', items.Count)
subsegment.addAnnotation('Status', 'SUCCESS')
} catch(err) {
// Exception Handling
//Tracing
subsegment.addAnnotation('Status', 'FAILED')
}
Now, let’s modify the getAllItems() method to also receive the subsegment as a parameter and create an additional subsegment to capture any business logic inside this method. We will be also adding the message payload as metadata.
const getAllItems = async (segment) => {
return AWSXRay.captureAsyncFunc('## getAllItemsData', async (subsegment) => {
// Initialization
try {
// Happy Path
//Tracing
subsegment.addMetadata('items', response)
} catch (err) {
// Exception Handling
} finally {
subsegment.close()
}
return response
}, segment);
}
Finally, modify the handler method to pass the subsegment to the getAllItems() method.
const items = await getAllItems(subsegment)
Save your changes to the serverless-observability-workshop/code/sample-app-tracing/src/handlers/get-all-items.js file.
Your entire file should look like the code below:
const AWSXRay = require('aws-xray-sdk-core')
const AWS = AWSXRay.captureAWS(require('aws-sdk'))
const docClient = new AWS.DynamoDB.DocumentClient()
exports.getAllItemsHandler = async (event, context) => {
return AWSXRay.captureAsyncFunc('## Handler', async (subsegment) => {
let response
try {
if (event.httpMethod !== 'GET') {
throw new Error(`getAllItems only accept GET method, you tried: ${event.httpMethod}`)
}
const items = await getAllItems(subsegment)
response = {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(items)
}
//Tracing
subsegment.addAnnotation('ItemsCount', items.Count)
subsegment.addAnnotation('Status', 'SUCCESS')
} catch (err) {
//Tracing
subsegment.addAnnotation('Status', 'FAILED')
response = {
statusCode: 500,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(err)
}
} finally {
subsegment.close()
}
return response
}, AWSXRay.getSegment());
}
const getAllItems = async (segment) => {
return AWSXRay.captureAsyncFunc('## getAllItemsData', async (subsegment) => {
let response
try {
var params = {
TableName: process.env.SAMPLE_TABLE
}
response = await docClient.scan(params).promise()
//Tracing
subsegment.addMetadata('items', response)
} catch (err) {
throw err
} finally {
subsegment.close()
}
return response
}, segment);
}