AWS X-Ray SDK Express Middleware

3.12.0 · active · verified Wed Apr 22

The `aws-xray-sdk-express` package provides middleware functions for Express.js applications to integrate with AWS X-Ray, enabling distributed tracing for incoming requests and outgoing responses. As part of the broader `aws-xray-sdk-node` monorepo, its current stable version is 3.12.0, with regular updates following the main SDK. It supports both automatic and manual tracing modes. The automatic mode, which is the default, utilizes the `cls-hooked` package for automatic context propagation across asynchronous operations, simplifying segment and subsegment management. Key differentiators include its official AWS support, seamless integration with Express.js routing, and the flexibility to choose between automatic and manual tracing paradigms to suit different application complexities and debugging needs. It requires Express 4.14.0 or greater and `aws-xray-sdk-core` as a peer dependency.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates setting up an Express application with AWS X-Ray tracing in automatic mode, including middleware for segment opening/closing, accessing the current segment, adding annotations and metadata, and handling subsegments for internal operations. It also includes basic error handling.

import express, { Request, Response, NextFunction } from 'express';
import * as AWSXRay from 'aws-xray-sdk-core';
import * as xrayExpress from 'aws-xray-sdk-express';

// Configure X-Ray SDK (defaults to environment variables like AWS_REGION, AWS_XRAY_DAEMON_ADDRESS)
// For local testing without a daemon, you might set the logger to console and disable daemon sending.
// AWSXRay.setLogger(console);
// AWSXRay.setDaemonAddress('127.0.0.1:2000'); // Default

const app = express();
const PORT = process.env.PORT || 3000;

// 1. Initialize X-Ray: This middleware *must* be added before defining any routes to be traced.
// In automatic mode, it is crucial that this is the LAST middleware added before your routes.
// 'ExpressMicroservice' is the name that will appear for your service in X-Ray traces.
app.use(xrayExpress.openSegment('ExpressMicroservice'));

// Define your application routes
app.get('/', (req: Request, res: Response) => {
  // In automatic mode, getSegment() retrieves the current segment from the context.
  const segment = AWSXRay.getSegment();
  if (segment) {
    segment.addAnnotation('route', 'home');
    segment.addMetadata('user', { id: 'test-user-123', session: 'abc' });
    console.log(`Tracing home route within segment: ${segment.id}`);
  } else {
    console.warn('No X-Ray segment found for home route.');
  }
  res.send('Hello from X-Ray Traced Express App!');
});

app.get('/data', async (req: Request, res: Response) => {
  const segment = AWSXRay.getSegment();
  if (segment) {
    // Create a subsegment for an internal asynchronous operation
    const subsegment = segment.addNewSubsegment('fetchDataOperation');
    subsegment.addAnnotation('data_type', 'user_profile');
    await new Promise(resolve => setTimeout(resolve, 100)); // Simulate async work
    subsegment.close(); // Important to close subsegments
    console.log(`Tracing data route within segment: ${segment.id}`);
  } else {
    console.warn('No X-Ray segment found for data route.');
  }
  res.json({ message: 'Data fetched successfully' });
});

// 2. Close X-Ray Segment: This middleware *must* be added after all routes to be traced.
// In automatic mode, it must be the FIRST middleware added AFTER your routes (or before error handlers).
app.use(xrayExpress.closeSegment());

// Optional: Error handling middleware for tracing errors
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  if (AWSXRay.isCurrentSegmentAvailable()) {
      AWSXRay.getSegment()?.addError(err);
  }
  console.error('An error occurred:', err.message);
  res.status(500).send('Something broke!');
});

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
  console.log('Ensure X-Ray daemon is running locally or AWS credentials/environment variables are configured for tracing.');
});

view raw JSON →