Notes On AWS X-Ray - A Distributed Tracing Mechanism
AWS X-Ray works with following services:
With X-Ray, you can trace requests made to applications that span multiple AWS accounts, AWS Regions, and Availability Zones.
First, enable "active tracing" configuration on the Lambda functions console.
You need atleast following privileges:
{
"Effect":"Allow", "Action": [ "xray:PutTraceSegments", "xray:PutTelemetryRecords" ], "Resource":[ "*" ] }
You need serverless-plugin-tracing as dev dependency so that you can have tracing:true inside provider section in serverless.yml file.
You need aws-xray-sdk as runtime dependency package. (It is not available by default in lambda container!)
# If you plan to use only manual mode ...
yarn add aws-xray-sdk-core # If you just need minimal functions.
AWSXRay.enableManualMode()
const segment = new AWSXRay.Segment('hello')
...
if (err) segment.addError(err)
..
segment.close()
// ################### Using Subsegments ######################
AWSXRay.enableManualMode();
const segment = new AWSXRay.Segment('hello function')
...
slowSubsegment = segment.addNewSubsegment('Slow Function')
...
if (err) slowSubsegment.addError(err)
...
slowSubsegment.close()
// ######## Using Top level Segments instead of Subsegments ####
new AWSXRay.Segment('Segment Name', parentSegment.trace_id, parentSegment.id);
// This will show the new segments in console trace graph.
//
// To get current global segment : AWSXRay.getSegment()
//
// ############################################################
// Full functionality ...
var XRay = require('aws-xray-sdk');
var AWS = XRay.captureAWS(require('aws-sdk'));
var http = XRay.captureHTTPs(require('http'));
...
AWS.config.region = process.env.REGION
#
# Use plugins that you want to trace for.
#
XRay.config([XRay.plugins.EC2Plugin, XRay.plugins.ElasticBeanstalkPlugin]);
# What is middleware ?
XRay.middleware.setSamplingRules('sampling-rules.json');
XRay.middleware.enableDynamicNaming();
var app = express();
var sns = new AWS.SNS();
var ddb = new AWS.DynamoDB();
// Create new segment for use with express app as middleware
app.use(XRay.express.openSegment('myfrontend'));
....
export const slowFunction = async () => {
await new Promise(resolve => setTimeout(resolve, 2000))
}
export const fasterFunction = async () => {
await new Promise(resolve => setTimeout(resolve, 150))
}
export const unreliableFunction = async () => {
if(Math.random() < 0.2) {
throw new Error('Something went wrong')
}
}
In serverless.yml, you just say tracing:true in Provider section with the help of serverless-plugin-tracing. This is the shortcut for doing the following for each function :
resources:
Resources:
#add aws xray config to our functions
CreateLambdaFunction:
Type: AWS::Lambda::Function
Properties:
TracingConfig:
Mode:
Active
See git@github.com:functionalone/aws-least-privilege.git
const AWSXRay = require('aws-xray-sdk-core');
AWSXRay.captureHTTPsGlobal(require('http'));
AWSXRay.captureAWS(require('aws-sdk'));
AWSXRay.capturePromise();
AWSXRay.setLogger(logger.child({'xray': true}));
aws xray get-trace-summaries --start-time ... --end-time ...
AWSXRay.captureAsyncFunc("getting restaurants", async_f, AWSXRay.getSegment());
// use request-id header
const requestId = context.awsRequestId;
Use correlation id