AWS X-Ray SDK for Node.js - AWS X-Ray

AWS X-Ray SDK for Node.js

The X-Ray SDK for Node.js is a library for Express web applications and Node.js Lambda functions that provides classes and methods for generating and sending trace data to the X-Ray daemon. Trace data includes information about incoming HTTP requests served by the application, and calls that the application makes to downstream services using the AWS SDK or HTTP clients.

Note

The X-Ray SDK for Node.js is an open source project that is supported for Node.js versions 14.x and up. You can follow the project and submit issues and pull requests on GitHub: github.com/aws/aws-xray-sdk-node

If you use Express, start by adding the SDK as middleware on your application server to trace incoming requests. The middleware creates a segment for each traced request, and completes the segment when the response is sent. While the segment is open you can use the SDK client's methods to add information to the segment and create subsegments to trace downstream calls. The SDK also automatically records exceptions that your application throws while the segment is open.

For Lambda functions called by an instrumented application or service, Lambda reads the tracing header and traces sampled requests automatically. For other functions, you can configure Lambda to sample and trace incoming requests. In either case, Lambda creates the segment and provides it to the X-Ray SDK.

Note

On Lambda, the X-Ray SDK is optional. If you don't use it in your function, your service map will still include a node for the Lambda service, and one for each Lambda function. By adding the SDK, you can instrument your function code to add subsegments to the function segment recorded by Lambda. See AWS Lambda and AWS X-Ray for more information.

Next, use the X-Ray SDK for Node.js to instrument your AWS SDK for JavaScript in Node.js clients. Whenever you make a call to a downstream AWS service or resource with an instrumented client, the SDK records information about the call in a subsegment. AWS services and the resources that you access within the services appear as downstream nodes on the trace map to help you identify errors and throttling issues on individual connections.

The X-Ray SDK for Node.js also provides instrumentation for downstream calls to HTTP web APIs and SQL queries. Wrap your HTTP client in the SDK's capture method to record information about outgoing HTTP calls. For SQL clients, use the capture method for your database type.

The middleware applies sampling rules to incoming requests to determine which requests to trace. You can configure the X-Ray SDK for Node.js to adjust the sampling behavior or to record information about the AWS compute resources on which your application runs.

Record additional information about requests and the work that your application does in annotations and metadata. Annotations are simple key-value pairs that are indexed for use with filter expressions, so that you can search for traces that contain specific data. Metadata entries are less restrictive and can record entire objects and arrays — anything that can be serialized into JSON.

Annotations and Metadata

Annotations and metadata are arbitrary text that you add to segments with the X-Ray SDK. Annotations are indexed for use with filter expressions. Metadata are not indexed, but can be viewed in the raw segment with the X-Ray console or API. Anyone that you grant read access to X-Ray can view this data.

When you have a lot of instrumented clients in your code, a single request segment can contain a large number of subsegments, one for each call made with an instrumented client. You can organize and group subsegments by wrapping client calls in custom subsegments. You can create a custom subsegment for an entire function or any section of code, and record metadata and annotations on the subsegment instead of writing everything on the parent segment.

For reference documentation about the SDK's classes and methods, see the AWS X-Ray SDK for Node.js API Reference.

Requirements

The X-Ray SDK for Node.js requires Node.js and the following libraries:

  • atomic-batcher – 1.0.2

  • cls-hooked – 4.2.2

  • pkginfo – 0.4.0

  • semver – 5.3.0

The SDK pulls these libraries in when you install it with NPM.

To trace AWS SDK clients, the X-Ray SDK for Node.js requires a minimum version of the AWS SDK for JavaScript in Node.js.

  • aws-sdk – 2.7.15

Dependency management

The X-Ray SDK for Node.js is available from NPM.

For local development, install the SDK in your project directory with npm.

~/nodejs-xray$ npm install aws-xray-sdk aws-xray-sdk@3.3.3 ├─┬ aws-xray-sdk-core@3.3.3 │ ├── @aws-sdk/service-error-classification@3.15.0 │ ├── @aws-sdk/types@3.15.0 │ ├─┬ @types/cls-hooked@4.3.3 │ │ └── @types/node@15.3.0 │ ├── atomic-batcher@1.0.2 │ ├─┬ cls-hooked@4.2.2 │ │ ├─┬ async-hook-jl@1.7.6 │ │ │ └── stack-chain@1.3.7 │ │ └─┬ emitter-listener@1.1.2 │ │ └── shimmer@1.2.1 │ └── semver@5.7.1 ├── aws-xray-sdk-express@3.3.3 ├── aws-xray-sdk-mysql@3.3.3 └── aws-xray-sdk-postgres@3.3.3

Use the --save option to save the SDK as a dependency in your application's package.json.

~/nodejs-xray$ npm install aws-xray-sdk --save aws-xray-sdk@3.3.3

If your application has any dependencies whose versions conflict with the X-Ray SDK's dependencies, both versions will be installed to ensure compatibility. For more details, see the official NPM documentation for dependency resolution.

Node.js samples

Work with the AWS X-Ray SDK for Node.js to get an end-to-end view of requests as they travel through your Node.js applications.

Configuring the X-Ray SDK for Node.js

You can configure the X-Ray SDK for Node.js with plugins to include information about the service that your application runs on, modify the default sampling behavior, or add sampling rules that apply to requests to specific paths.

Service plugins

Use plugins to record information about the service hosting your application.

Plugins
  • Amazon EC2 – EC2Plugin adds the instance ID, Availability Zone, and the CloudWatch Logs Group.

  • Elastic Beanstalk – ElasticBeanstalkPlugin adds the environment name, version label, and deployment ID.

  • Amazon ECS – ECSPlugin adds the container ID.

To use a plugin, configure the X-Ray SDK for Node.js client by using the config method.

Example app.js - plugins
var AWSXRay = require('aws-xray-sdk'); AWSXRay.config([AWSXRay.plugins.EC2Plugin,AWSXRay.plugins.ElasticBeanstalkPlugin]);

The SDK also uses plugin settings to set the origin field on the segment. This indicates the type of AWS resource that runs your application. When you use multiple plugins, the SDK uses the following resolution order to determine the origin: ElasticBeanstalk > EKS > ECS > EC2.

Sampling rules

The SDK uses the sampling rules you define in the X-Ray console to determine which requests to record. The default rule traces the first request each second, and five percent of any additional requests across all services sending traces to X-Ray. Create additional rules in the X-Ray console to customize the amount of data recorded for each of your applications.

The SDK applies custom rules in the order in which they are defined. If a request matches multiple custom rules, the SDK applies only the first rule.

Note

If the SDK can't reach X-Ray to get sampling rules, it reverts to a default local rule of the first request received at the beginning of each second, and five percent of any additional requests per host. This can occur if the host doesn't have permission to call sampling APIs, or can't connect to the X-Ray daemon, which acts as a TCP proxy for API calls made by the SDK.

You can also configure the SDK to load sampling rules from a JSON document. The SDK can use local rules as a backup for cases where X-Ray sampling is unavailable, or use local rules exclusively.

Example sampling-rules.json
{ "version": 2, "rules": [ { "description": "Player moves.", "host": "*", "http_method": "*", "url_path": "/api/move/*", "fixed_target": 0, "rate": 0.05 } ], "default": { "fixed_target": 1, "rate": 0.1 } }

This example defines one custom rule and a default rule. The custom rule applies a five-percent sampling rate with no minimum number of requests to trace for paths under /api/move/. The default rule traces the first request each second and 10 percent of additional requests.

The disadvantage of defining rules locally is that the fixed target is applied by each instance of the recorder independently, instead of being managed by the X-Ray service. As you deploy more hosts, the fixed rate is multiplied, making it harder to control the amount of data recorded.

On AWS Lambda, you cannot modify the sampling rate. If your function is called by an instrumented service, calls that generated requests that were sampled by that service will be recorded by Lambda. If active tracing is enabled and no tracing header is present, Lambda makes the sampling decision.

To configure backup rules, tell the X-Ray SDK for Node.js to load sampling rules from a file with setSamplingRules.

Example app.js - sampling rules from a file
var AWSXRay = require('aws-xray-sdk'); AWSXRay.middleware.setSamplingRules('sampling-rules.json');

You can also define your rules in code and pass them to setSamplingRules as an object.

Example app.js - sampling rules from an object
var AWSXRay = require('aws-xray-sdk'); var rules = { "rules": [ { "description": "Player moves.", "service_name": "*", "http_method": "*", "url_path": "/api/move/*", "fixed_target": 0, "rate": 0.05 } ], "default": { "fixed_target": 1, "rate": 0.1 }, "version": 1 } AWSXRay.middleware.setSamplingRules(rules);

To use only local rules, call disableCentralizedSampling.

AWSXRay.middleware.disableCentralizedSampling()

Logging

To log output from the SDK, call AWSXRay.setLogger(logger), where logger is an object that provides standard logging methods (warn, info, etc.).

By default the SDK will log error messages to the console using the standard methods on the console object. The log level of the built-in logger can be set by using either the AWS_XRAY_DEBUG_MODE or AWS_XRAY_LOG_LEVEL environment variables. For a list of valid log level values, see Environment variables.

If you wish to provide a different format or destination for the logs then you can provide the SDK with your own implementation of the logger interface as shown below. Any object that implements this interface can be used. This means that many logging libraries, e.g. Winston, could be used and passed to the SDK directly.

Example app.js - logging
var AWSXRay = require('aws-xray-sdk'); // Create your own logger, or instantiate one using a library. var logger = { error: (message, meta) => { /* logging code */ }, warn: (message, meta) => { /* logging code */ }, info: (message, meta) => { /* logging code */ }, debug: (message, meta) => { /* logging code */ } } AWSXRay.setLogger(logger); AWSXRay.config([AWSXRay.plugins.EC2Plugin]);

Call setLogger before you run other configuration methods to ensure that you capture output from those operations.

X-Ray daemon address

If the X-Ray daemon listens on a port or host other than 127.0.0.1:2000, you can configure the X-Ray SDK for Node.js to send trace data to a different address.

AWSXRay.setDaemonAddress('host:port');

You can specify the host by name or by IPv4 address.

Example app.js - daemon address
var AWSXRay = require('aws-xray-sdk'); AWSXRay.setDaemonAddress('daemonhost:8082');

If you configured the daemon to listen on different ports for TCP and UDP, you can specify both in the daemon address setting.

Example app.js - daemon address on separate ports
var AWSXRay = require('aws-xray-sdk'); AWSXRay.setDaemonAddress('tcp:daemonhost:8082 udp:daemonhost:8083');

You can also set the daemon address by using the AWS_XRAY_DAEMON_ADDRESS environment variable.

Environment variables

You can use environment variables to configure the X-Ray SDK for Node.js. The SDK supports the following variables.

  • AWS_XRAY_CONTEXT_MISSING – Set to RUNTIME_ERROR to throw exceptions when your instrumented code attempts to record data when no segment is open.

    Valid Values
    • RUNTIME_ERROR – Throw a runtime exception.

    • LOG_ERROR – Log an error and continue (default).

    • IGNORE_ERROR – Ignore error and continue.

    Errors related to missing segments or subsegments can occur when you attempt to use an instrumented client in startup code that runs when no request is open, or in code that spawns a new thread.

  • AWS_XRAY_DAEMON_ADDRESS – Set the host and port of the X-Ray daemon listener. By default, the SDK uses 127.0.0.1:2000 for both trace data (UDP) and sampling (TCP). Use this variable if you have configured the daemon to listen on a different port or if it is running on a different host.

    Format
    • Same portaddress:port

    • Different portstcp:address:port udp:address:port

  • AWS_XRAY_DEBUG_MODE – Set to TRUE to configure the SDK to output logs to the console, at debug level.

  • AWS_XRAY_LOG_LEVEL – Set a log level for the default logger. Valid values are debug, info, warn, error, and silent. This value is ignored when AWS_XRAY_DEBUG_MODE is set to TRUE.

  • AWS_XRAY_TRACING_NAME – Set a service name that the SDK uses for segments. Overrides the segment name that you set on the Express middleware.

Tracing incoming requests with the X-Ray SDK for Node.js

You can use the X-Ray SDK for Node.js to trace incoming HTTP requests that your Express and Restify applications serve on an EC2 instance in Amazon EC2, AWS Elastic Beanstalk, or Amazon ECS.

The X-Ray SDK for Node.js provides middleware for applications that use the Express and Restify frameworks. When you add the X-Ray middleware to your application, the X-Ray SDK for Node.js creates a segment for each sampled request. This segment includes timing, method, and disposition of the HTTP request. Additional instrumentation creates subsegments on this segment.

Note

For AWS Lambda functions, Lambda creates a segment for each sampled request. See AWS Lambda and AWS X-Ray for more information.

Each segment has a name that identifies your application in the service map. The segment can be named statically, or you can configure the SDK to name it dynamically based on the host header in the incoming request. Dynamic naming lets you group traces based on the domain name in the request, and apply a default name if the name doesn't match an expected pattern (for example, if the host header is forged).

Forwarded Requests

If a load balancer or other intermediary forwards a request to your application, X-Ray takes the client IP from the X-Forwarded-For header in the request instead of from the source IP in the IP packet. The client IP that is recorded for a forwarded request can be forged, so it should not be trusted.

When a request is forwarded, the SDK sets an additional field in the segment to indicate this. If the segment contains the field x_forwarded_for set to true, the client IP was taken from the X-Forwarded-For header in the HTTP request.

The message handler creates a segment for each incoming request with an http block that contains the following information:

  • HTTP method – GET, POST, PUT, DELETE, etc.

  • Client address – The IP address of the client that sent the request.

  • Response code – The HTTP response code for the completed request.

  • Timing – The start time (when the request was received) and end time (when the response was sent).

  • User agent — The user-agent from the request.

  • Content length — The content-length from the response.

Tracing incoming requests with Express

To use the Express middleware, initialize the SDK client and use the middleware returned by the express.openSegment function before you define your routes.

Example app.js - Express
var app = express(); var AWSXRay = require('aws-xray-sdk'); app.use(AWSXRay.express.openSegment('MyApp')); app.get('/', function (req, res) { res.render('index'); }); app.use(AWSXRay.express.closeSegment());

After you define your routes, use the output of express.closeSegment as shown to handle any errors returned by the X-Ray SDK for Node.js.

Tracing incoming requests with restify

To use the Restify middleware, initialize the SDK client and run enable. Pass it your Restify server and segment name.

Example app.js - restify
var AWSXRay = require('aws-xray-sdk'); var AWSXRayRestify = require('aws-xray-sdk-restify'); var restify = require('restify'); var server = restify.createServer(); AWSXRayRestify.enable(server, 'MyApp')); server.get('/', function (req, res) { res.render('index'); });

Configuring a segment naming strategy

AWS X-Ray uses a service name to identify your application and distinguish it from the other applications, databases, external APIs, and AWS resources that your application uses. When the X-Ray SDK generates segments for incoming requests, it records your application's service name in the segment's name field.

The X-Ray SDK can name segments after the hostname in the HTTP request header. However, this header can be forged, which could result in unexpected nodes in your service map. To prevent the SDK from naming segments incorrectly due to requests with forged host headers, you must specify a default name for incoming requests.

If your application serves requests for multiple domains, you can configure the SDK to use a dynamic naming strategy to reflect this in segment names. A dynamic naming strategy allows the SDK to use the hostname for requests that match an expected pattern, and apply the default name to requests that don't.

For example, you might have a single application serving requests to three subdomains– www.example.com, api.example.com, and static.example.com. You can use a dynamic naming strategy with the pattern *.example.com to identify segments for each subdomain with a different name, resulting in three service nodes on the service map. If your application receives requests with a hostname that doesn't match the pattern, you will see a fourth node on the service map with a fallback name that you specify.

To use the same name for all request segments, specify the name of your application when you initialize the middleware, as shown in the previous sections.

Note

You can override the default service name that you define in code with the AWS_XRAY_TRACING_NAME environment variable.

A dynamic naming strategy defines a pattern that hostnames should match, and a default name to use if the hostname in the HTTP request does not match the pattern. To name segments dynamically, use AWSXRay.middleware.enableDynamicNaming.

Example app.js - dynamic segment names

If the hostname in the request matches the pattern *.example.com, use the hostname. Otherwise, use MyApp.

var app = express(); var AWSXRay = require('aws-xray-sdk'); app.use(AWSXRay.express.openSegment('MyApp')); AWSXRay.middleware.enableDynamicNaming('*.example.com'); app.get('/', function (req, res) { res.render('index'); }); app.use(AWSXRay.express.closeSegment());

Tracing calls to downstream HTTP web services using the X-Ray SDK for Node.js

When your application makes calls to microservices or public HTTP APIs, you can use the X-Ray SDK for Node.js client to instrument those calls and add the API to the service graph as a downstream service.

Pass your http or https client to the X-Ray SDK for Node.js captureHTTPs method to trace outgoing calls.

Note

Calls using third-party HTTP request libraries, such as Axios or Superagent, are supported through the captureHTTPsGlobal() API and will still be traced when they use the native http module.

Example app.js - HTTP client
var AWSXRay = require('aws-xray-sdk'); var http = AWSXRay.captureHTTPs(require('http'));

To enable tracing on all HTTP clients, call captureHTTPsGlobal before you load http.

Example app.js - HTTP client (global)
var AWSXRay = require('aws-xray-sdk'); AWSXRay.captureHTTPsGlobal(require('http')); var http = require('http');

When you instrument a call to a downstream web API, the X-Ray SDK for Node.js records a subsegment that contains information about the HTTP request and response. X-Ray uses the subsegment to generate an inferred segment for the remote API.

Example Subsegment for a downstream HTTP call
{ "id": "004f72be19cddc2a", "start_time": 1484786387.131, "end_time": 1484786387.501, "name": "names.example.com", "namespace": "remote", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } } }
Example Inferred segment for a downstream HTTP call
{ "id": "168416dc2ea97781", "name": "names.example.com", "trace_id": "1-62be1272-1b71c4274f39f122afa64eab", "start_time": 1484786387.131, "end_time": 1484786387.501, "parent_id": "004f72be19cddc2a", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } }, "inferred": true }

Tracing SQL queries with the X-Ray SDK for Node.js

Instrument SQL database queries by wrapping your SQL client in the corresponding X-Ray SDK for Node.js client method.

  • PostgreSQLAWSXRay.capturePostgres()

    var AWSXRay = require('aws-xray-sdk'); var pg = AWSXRay.capturePostgres(require('pg')); var client = new pg.Client();
  • MySQLAWSXRay.captureMySQL()

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

When you use an instrumented client to make SQL queries, the X-Ray SDK for Node.js records information about the connection and query in a subsegment.

Including additional data in SQL subsegments

You can add additional information to subsegments generated for SQL queries, as long as it's mapped to an allow-listed SQL field. For example, to record the sanitized SQL query string in a subsegment, you can add it directly to the subsegment's SQL object.

Example Assign SQL to subsegment
const queryString = 'SELECT * FROM MyTable'; connection.query(queryString, ...); // Retrieve the most recently created subsegment const subs = AWSXRay.getSegment().subsegments; if (subs & & subs.length > 0) { var sqlSub = subs[subs.length - 1]; sqlSub.sql.sanitized_query = queryString; }

For a full list of allow-listed SQL fields, see the SQL Queries section in the X-Ray segment documents.

Generating custom subsegments with the X-Ray SDK for Node.js

Subsegments extend a trace's segment with details about work done in order to serve a request. Each time you make a call with an instrumented client, the X-Ray SDK records the information generated in a subsegment. You can create additional subsegments to group other subsegments, to measure the performance of a section of code, or to record annotations and metadata.

Custom Express subsegments

To create a custom subsegment for a function that makes calls to downstream services, use the captureAsyncFunc function.

Example app.js - custom subsegments Express
var AWSXRay = require('aws-xray-sdk'); app.use(AWSXRay.express.openSegment('MyApp')); app.get('/', function (req, res) { var host = 'api.example.com'; AWSXRay.captureAsyncFunc('send', function(subsegment) { sendRequest(host, function() { console.log('rendering!'); res.render('index'); subsegment.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(); };

In this example, the application creates a custom subsegment named send for calls to the sendRequest function. captureAsyncFunc passes a subsegment that you must close within the callback function when the asynchronous calls that it makes are complete.

For synchronous functions, you can use the captureFunc function, which closes the subsegment automatically as soon as the function block finishes executing.

When you create a subsegment within a segment or another subsegment, the X-Ray SDK for Node.js generates an ID for it and records the start time and end time.

Example Subsegment with metadata
"subsegments": [{ "id": "6f1605cd8a07cb70", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "Custom subsegment for UserModel.saveUser function", "metadata": { "debug": { "test": "Metadata string from UserModel.saveUser" } },

Custom Lambda subsegments

The SDK is configured to automatically create a placeholder facade segment when it detects it's running in Lambda. To create a basic subsegement, which will create a single AWS::Lambda::Function node on the X-Ray trace map, call and repurpose the facade segment. If you manually create a new segment with a new ID (while sharing the trace ID, parent ID and the sampling decision) you will be able to send a new segment.

Example app.js - manual custom subsegments
const segment = AWSXRay.getSegment(); //returns the facade segment const subsegment = segment.addNewSubsegment('subseg'); ... subsegment.close(); //the segment is closed by the SDK automatically

Add annotations and metadata to segments with the X-Ray SDK for Node.js

You can use annotations and metadata to record additional information about requests, the environment, or your application. You can add annotations and metadata to the segments that the X-Ray SDK creates, or to custom subsegments that you create.

Annotations are key-value pairs with string, number, or Boolean values. Annotations are indexed for use with filter expressions. Use annotations to record data that you want to use to group traces in the console, or when calling the GetTraceSummaries API.

Metadata are key-value pairs that can have values of any type, including objects and lists, but are not indexed for use with filter expressions. Use metadata to record additional data that you want stored in the trace but don't need to use with search.

In addition to annotations and metadata, you can also record user ID strings on segments. User IDs are recorded in a separate field on segments and are indexed for use with search.

Recording annotations with the X-Ray SDK for Node.js

Use annotations to record information on segments or subsegments that you want indexed for search.

Annotation Requirements
  • Keys – The key for an X-Ray annotation can have up to 500 alphanumeric characters. You cannot use spaces or symbols other than the underscore symbol (_).

  • Values – The value for an X-Ray annotation can have up to 1,000 Unicode characters.

  • The number of Annotations – You can use up to 50 annotations per trace.

To record annotations
  1. Get a reference to the current segment or subsegment.

    var AWSXRay = require('aws-xray-sdk'); ... var document = AWSXRay.getSegment();
  2. Call addAnnotation with a String key, and a Boolean, Number, or String value.

    document.addAnnotation("mykey", "my value");

The SDK records annotations as key-value pairs in an annotations object in the segment document. Calling addAnnotation twice with the same key overwrites previously recorded values on the same segment or subsegment.

To find traces that have annotations with specific values, use the annotations.key keyword in a filter expression.

Example app.js - annotations
var AWS = require('aws-sdk'); var AWSXRay = require('aws-xray-sdk'); var ddb = AWSXRay.captureAWSClient(new AWS.DynamoDB()); ... app.post('/signup', function(req, res) { var item = { 'email': {'S': req.body.email}, 'name': {'S': req.body.name}, 'preview': {'S': req.body.previewAccess}, 'theme': {'S': req.body.theme} }; var seg = AWSXRay.getSegment(); seg.addAnnotation('theme', req.body.theme); ddb.putItem({ 'TableName': ddbTable, 'Item': item, 'Expected': { email: { Exists: false } } }, function(err, data) { ...

Recording metadata with the X-Ray SDK for Node.js

Use metadata to record information on segments or subsegments that you don't need indexed for search. Metadata values can be strings, numbers, Booleans, or any other object that can be serialized into a JSON object or array.

To record metadata
  1. Get a reference to the current segment or subsegment.

    var AWSXRay = require('aws-xray-sdk'); ... var document = AWSXRay.getSegment();
  2. Call addMetadata with a string key, a Boolean, number, string, or object value, and a string namespace.

    document.addMetadata("my key", "my value", "my namespace");

    or

    Call addMetadata with just a key and value.

    document.addMetadata("my key", "my value");

If you don't specify a namespace, the SDK uses default. Calling addMetadata twice with the same key overwrites previously recorded values on the same segment or subsegment.

Recording user IDs with the X-Ray SDK for Node.js

Record user IDs on request segments to identify the user who sent the request. This operation isn’t compatible with AWS Lambda functions because segments in Lambda environments are immutable. The setUser call can be applied only to segments, not subsegments.

To record user IDs
  1. Get a reference to the current segment or subsegment.

    var AWSXRay = require('aws-xray-sdk'); ... var document = AWSXRay.getSegment();
  2. Call setUser() with a string ID of the user who sent the request.

    var user = 'john123'; AWSXRay.getSegment().setUser(user);

You can call setUser to record the user ID as soon as your express application starts processing a request. If you will use the segment only to set the user ID, you can chain the calls in a single line.

Example app.js - user ID
var AWS = require('aws-sdk'); var AWSXRay = require('aws-xray-sdk'); var uuidv4 = require('uuid/v4'); var ddb = AWSXRay.captureAWSClient(new AWS.DynamoDB()); ... app.post('/signup', function(req, res) { var userId = uuidv4(); var item = { 'userId': {'S': userId}, 'email': {'S': req.body.email}, 'name': {'S': req.body.name} }; var seg = AWSXRay.getSegment().setUser(userId); ddb.putItem({ 'TableName': ddbTable, 'Item': item, 'Expected': { email: { Exists: false } } }, function(err, data) { ...

To find traces for a user ID, use the user keyword in a filter expression.