JSPM

  • Created
  • Published
  • Downloads 413047
  • Score
    100M100P100Q177797F
  • License Apache-2.0

AWS X-Ray SDK for Javascript

Package Exports

  • aws-xray-sdk

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (aws-xray-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Setup development environment

npm install

Run tests

npm test

Generate docs

grunt docs

Requirements

AWS SDK v2.7.15 or greater.

AWS X-Ray

AWS X-Ray automatically records information for incoming and outgoing requests and responses, as well as local data such as function calls, time, variables (via metadata and annotations), even EC2 instance data. Currently only supports Express applications for auto capturing.

The AWS X-Ray SDK has two modes - Manual and CLS. CLS mode uses the Continuation Local Storage package and automatically keeps track of the current segment and subsegment. This is the default mode. Manual mode requires you pass around the segment reference.

In CLS mode, you can get the current segment/subsegment at any time: var segment = AWSXRay.getSegment();

In manual mode, you can get the base segment off the request object: var segment = req.segment;

  • In manual mode, you must pass along the reference to the current subsegment.
  • If you are not using the express middleware, and you create your segment manually, you must close it with segment.close().

The SDK exposes the Segment and Subsegment objects to create your own capturing mechanisms, but a few are supplied. These keep the current subsegment up to date automatically using CLS.

AWSXRay.capture - Takes a function that takes a single subsegment argument. This will create a new nested subsegment and expose it. The segment will close automatically when the function completes executing. This will not correctly time functions with asynchronous calls, instead use captureAsync.

AWSXRay.captureAsync - Takes a function that takes a single subsegment argument. This will create a new nested subsegment and expose it. The segment must be closed manually using subsegment.close() or subsegment.close(error) when the asynchronous function completes.

AWSXRay.captureCallback - Takes a function to be used as a callback. Useful for capturing callback information and directly associate it to the call that generated it. This will create a new nested subsegment and expose it by appending it onto the arguments used to call the callback. For this reason, always call your captured callbacks with the full parameter list. The subsegment will close automatically when the function completes executing.

Setup

environment variables

Environment variables always override values set in code.

AWS_XRAY_DEBUG_MODE              Enables logging to console output (otherwise outputs to AWSXRay.log).
AWS_XRAY_TRACING_NAME            For overriding the default segment name to be used with the middleware. See dynamic and fixed naming modes.
XRAY_TRACING_NAME                For overriding the default segment name to be used with the middleware. See dynamic and fixed naming modes.
                                  **This will be deprecated in favor of AWS_XRAY_TRACING_NAME for the GA release.

AWS_XRAY_DAEMON_ADDRESS          For setting the daemon address and port. Expects 'x.x.x.x', ':yyyy' or 'x.x.x.x:yyyy' IPv4 formats.

POSTGRES_DATABASE_VERSION        Sets additional data for the sql subsegment.
POSTGRES_DRIVER_VERSION          Sets additional data for the sql subsegment.

MYSQL_DATABASE_VERSION           Sets additional data for the sql subsegment.
MYSQL_DRIVER_VERSION             Sets additional data for the sql subsegment.

daemon configuration

By default, the SDK expects the daemon to be at 127.0.0.1 (localhost) on port 2000. You can override the address, port, or both. This can be changed via the environment variables listed above, or through code. The same format is applicable for both.

AWSXRay.setDaemonAddress('186.34.0.23:8082');
AWSXRay.setDaemonAddress(':8082');
AWSXRay.setDaemonAddress('186.34.0.23');

middleware - dynamic and fixed naming modes

The SDK requires a default segment name to be set when using the middleware. If it is not set, an error will be thrown. This value can be overridden via the AWS_XRAY_TRACING_NAME (or XRAY_TRACING_NAME) environment variable.

app.use(AWSXRay.express.openSegment('defaultName'));

The SDK defaults to a fixed naming mode. This means that each time a new segment is created for an incoming request, the name of that segment is set to the default name.

In dynamic mode, the segment name can vary between the host header of the request or the default name.

AWSXRay.middleware.enableDynamicNaming(<pattern>);

If no pattern is provided, the host header is used as the segment name. If no host header is present, the default is used. This is equivalent to using the pattern '*'.

If a pattern is provided, in the form of a string with wild cards (ex: '..us-east-1.elasticbeanstalk.com') then the host header of the request will be checked against it. If the host header is present and matches this pattern, it is used as the segment name. Otherwise, the default name is used.

version capturing

Use the 'npm start' script to enable.

capture all incoming HTTP requests to '/'

var app = express();

//...

var AWSXRay = require('aws-xray-sdk');

app.use(AWSXRay.express.openSegment('defaultName'));               //required at the start of your routes

app.get('/', function (req, res) {
  res.render('index');
});

app.use(AWSXRay.express.closeSegment());   //required at the end of your routes / first in error handling routes

capture all outgoing AWS requests

var AWS = captureAWS(require('aws-sdk'));

//create new clients as per usual
//make sure any outgoing calls that are dependent on another async
//function are wrapped with captureAsync, otherwise duplicate segments may leak
//see usages for clients in manual and CLS modes

configure AWSXRay to automatically capture EC2 instance data

var AWSXRay = require('aws-xray-sdk');
AWSXRay.config([AWSXRay.plugins.EC2]);

add annotations

var key = 'hello';
var value = 'there';        // must be string, boolean or finite number

subsegment.addAnnotation(key, value);

add metadata

var key = 'hello';
var value = 'there';

subsegment.addMetadata(key, value);

create new subsegment

var newSubseg = subsegment.addNewSubsegment(name);

// or

var subsegment = new Subsegment(name);

CLS Mode Examples

capture all incoming HTTP requests to '/'

var app = express();

//...

var AWSXRay = require('aws-xray-sdk');

app.use(AWSXRay.express.openSegment('defaultName'));

app.get('/', function (req, res) {
  res.render('index');
});

app.use(AWSXRay.express.closeSegment());

capture through function calls

var AWSXRay = require('aws-xray-sdk');

app.use(AWSXRay.express.openSegment('defaultName'));

app.get('/', function (req, res) {
  var host = 'samplego-env.us-east-1.elasticbeanstalk.com';

  AWSXRay.captureAsync('send', function(seg) {
    sendRequest(host, function() {
      console.log("rendering!");
      res.render('index');
      seg.close();
    });
  });
});

app.use(AWSXRay.express.closeSegment());

function sendRequest(host, cb) {
  var options = {
    host: host,
    path: '/',
  };

  var callback = function(response) {
    var str = '';

    response.on('data', function (chunk) {
      str += chunk;
    });

    response.on('end', function () {
      cb();
    });
  }

  http.request(options, callback).end();
};

capture outgoing AWS requests on a single client

var s3 = AWSXRay.captureAWSClient(new AWS.S3());

//use client as usual
//make sure any outgoing calls that are dependent on another async
//function are wrapped with captureAsync, otherwise duplicate segments may leak

capture outgoing AWS requests on every AWS SDK client

var aws = AWSXRay.captureAWS(require('aws-sdk'));

//create new clients as per usual
//make sure any outgoing calls that are dependent on another async
//function are wrapped with captureAsync, otherwise duplicate segments may leak

capture all outgoing HTTP/S requests

AWSXRay.captureHTTPs(http);     //patching the http module will patch for https as well

var options = {
  ...
}

http.request(options, callback).end();

//create new requests as per usual
//make sure any outgoing calls that are dependent on another async
//function are wrapped with captureAsync, otherwise duplicate segments may leak

capture PostgreSQL queries

var AWSXRay = require('aws-xray-sdk');

var pg = AWSXRay.capturePostgres(require('pg'));

...

var client = new pg.Client();

client.connect(function (err) {
  ...

  client.query({name: 'moop', text: 'SELECT $1::text as name'}, ['brianc'], function (err, result) {
    //automatically captures query information and error (if any)
  });
});

...

var pool = new pg.Pool(config);
pool.connect(function(err, client, done) {
  if(err) {
    return console.error('error fetching client from pool', err);
  }
  var query = client.query('SELECT * FROM mytable', function(err, result) {
    //automatically captures query information and error (if any)
  });
});

capture MySQL queries

var AWSXRay = require('aws-xray-sdk');

var mysql = AWSXRay.captureMySQL(require('mysql'));

var config = { ... };

...

var connection = mysql.createConnection(config);

connection.query('SELECT * FROM cats', function(err, rows) {
  //automatically captures query information and error (if any)
});

...

var pool = mysql.createPool(config);
var segment = req.segment;

pool.query('SELECT * FROM cats', function(err, rows, fields) {
  //automatically captures query information and error (if any)
}

Manual Mode

Enable manual mode:

AWSXRay.enableManualMode();

capture through function calls

var AWSXRay = require('aws-xray-sdk');

AWSXRay.enableManualMode();

app.use(AWSXRay.express.openSegment('defaultName'));

app.get('/', function (req, res) {
  var segment = req.segment;
  var host = 'samplego-env.us-east-1.elasticbeanstalk.com';

  AWSXRay.captureAsync('send', function(seg) {
    sendRequest(host, function() {
      console.log("rendering!");
      res.render('index');
      seg.close();
    });
  }, segment);
});

app.use(AWSXRay.express.closeSegment());

function sendRequest(host, cb, segment) {
  var options = {
    host: host,
    path: '/',
    Segment: segment
  };

  var callback = function(response) {
    var str = '';

    //the whole response has been received, so we just print it out here
    //another chunk of data has been received, so append it to `str`
    response.on('data', function (chunk) {
      str += chunk;
    });

    response.on('end', function () {
      cb();
    });
  }

  http.request(options, callback).end();
};

capture outgoing AWS requests on a single client

var s3 = AWSXRay.captureAWSClient(new AWS.S3());
var params = {
  Bucket: bucketName,
  Key: keyName,
  Body: 'Hello!',
  Segment: subsegment             //required "Segment" param
};

s3.putObject(params, function(err, data) {
  ...
});

capture all outgoing AWS requests

var AWS = captureAWS(require('aws-sdk'));

//create new clients as per usual
//make sure any outgoing calls that are dependent on another async
//functions are wrapped, otherwise duplicate segments may leak.

capture all outgoing HTTP/S requests

AWSXRay.captureHTTPs(http);     //patching the http module will patch for https as well

...

//include segment/subsegment reference in options as 'Segment'
var options = {
  ...
  Segment: subsegment
}

http.request(options, callback).end();

capture PostgreSQL queries

var AWSXRay = require('aws-xray-sdk');
var pg = AWSXRay.capturePostgres(require('pg'));

...

var client = new pg.Client();

client.connect(function (err) {
  ...

  client.query({name: 'moop', text: 'SELECT $1::text as name'}, ['mcmuls'], function (err, result) {
    //automatically captures query information and error (if any)
  });
});

...

var pool = new pg.Pool(config);
pool.connect(function(err, client, done) {
  if(err) {
    return console.error('error fetching client from pool', err);
  }
  var query = client.query('SELECT * FROM mytable', function(err, result) {
    //automatically captures query information and error (if any)
  }, segment));
};

capture MySQL queries

var AWSXRay = require('aws-xray-sdk');
var mysql = AWSXRay.captureMySQL(require('mysql'));

var config = { ... };

...

var connection = mysql.createConnection(config);

connection.query('SELECT * FROM cats', function(err, rows) {
  //automatically captures query information and error (if any)
});

...

var pool = mysql.createPool(config);

pool.query('SELECT * FROM cats', function(err, rows, fields) {
  //automatically captures query information and error (if any)
}, segment);