or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

aws-sdk-instrumentation.mddecorator-tracing.mdindex.mdmanual-instrumentation.mdmiddleware-tracing.mdtypes.md
tile.json

middleware-tracing.mddocs/

Middleware Integration

Middleware-based tracing provides automatic instrumentation for function-based Lambda handlers using the Middy middleware framework. This pattern is ideal for functional programming styles and integrates seamlessly with other Middy middleware.

Capabilities

Capture Lambda Handler Middleware

Automatically trace Lambda handler execution with cold start detection and error handling using Middy middleware.

/**
 * Middy middleware automating capture of metadata and annotations on segments or subsegments for a Lambda Handler
 *
 * Automatically:
 * - Handles subsegment lifecycle
 * - Adds ColdStart annotation
 * - Adds ServiceName annotation
 * - Adds function response as metadata (configurable)
 * - Adds function error as metadata (if any)
 */
function captureLambdaHandler(
  target: Tracer,
  options?: CaptureLambdaHandlerOptions
): MiddlewareLikeObj;

interface CaptureLambdaHandlerOptions {
  /** Whether to capture the Lambda handler response as subsegment metadata (default: true) */
  captureResponse?: boolean;
}

interface MiddlewareLikeObj {
  before?: (request: MiddyLikeRequest) => void | Promise<void>;
  after?: (request: MiddyLikeRequest) => void | Promise<void>;
  onError?: (request: MiddyLikeRequest) => void | Promise<void>;
}

Basic Usage:

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import middy from '@middy/core';

const tracer = new Tracer({ serviceName: 'serverlessAirline' });

const lambdaHandler = async (event: unknown, context: unknown): Promise<void> => {
  // Handler logic - automatically traced
  tracer.putAnnotation('successfulBooking', true);
};

export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));

Disabling Response Capture:

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import middy from '@middy/core';

const tracer = new Tracer({ serviceName: 'paymentService' });

const lambdaHandler = async (event: PaymentEvent, context: unknown): Promise<PaymentResponse> => {
  // Process payment - response not captured due to sensitive data
  return { transactionId: '123', status: 'success' };
};

export const handler = middy(lambdaHandler).use(
  captureLambdaHandler(tracer, { captureResponse: false })
);

Complete Example

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';
import middy from '@middy/core';

const tracer = new Tracer({ serviceName: 'bookingService' });

// Instrument AWS SDK client
const dynamoDB = tracer.captureAWSv3Client(new DynamoDBClient({}));

interface BookingEvent {
  bookingId: string;
  userId: string;
}

interface BookingResponse {
  booking: {
    id: string;
    status: string;
  };
}

const lambdaHandler = async (
  event: BookingEvent,
  context: unknown
): Promise<BookingResponse> => {
  // Add custom annotations
  tracer.putAnnotation('bookingId', event.bookingId);
  tracer.putAnnotation('userId', event.userId);

  // Get booking from DynamoDB (automatically traced)
  const result = await dynamoDB.send(new GetItemCommand({
    TableName: 'Bookings',
    Key: { bookingId: { S: event.bookingId } }
  }));

  // Add metadata
  tracer.putMetadata('dbResponse', result);

  return {
    booking: {
      id: event.bookingId,
      status: 'confirmed'
    }
  };
};

// Wrap handler with middleware
export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));

Combining with Other Middleware

The Tracer middleware integrates seamlessly with other Middy middleware:

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import middy from '@middy/core';
import httpJsonBodyParser from '@middy/http-json-body-parser';
import httpErrorHandler from '@middy/http-error-handler';

const tracer = new Tracer({ serviceName: 'apiService' });

const lambdaHandler = async (event: APIEvent, context: unknown): Promise<APIResponse> => {
  tracer.putAnnotation('endpoint', event.path);

  // Business logic
  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Success' })
  };
};

export const handler = middy(lambdaHandler)
  .use(httpJsonBodyParser())
  .use(captureLambdaHandler(tracer))
  .use(httpErrorHandler());

Error Handling

The middleware automatically captures errors as metadata:

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import middy from '@middy/core';

const tracer = new Tracer({ serviceName: 'orderService' });

const lambdaHandler = async (event: OrderEvent, context: unknown): Promise<void> => {
  tracer.putAnnotation('orderId', event.orderId);

  // Simulate an error
  if (!event.isValid) {
    throw new Error('Invalid order');
  }

  // Process order
};

// Middleware will automatically capture the error as metadata
export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));

TypeScript Type Support

The middleware is fully typed and works with typed events and responses:

import { Tracer } from '@aws-lambda-powertools/tracer';
import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware';
import type { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import middy from '@middy/core';

const tracer = new Tracer({ serviceName: 'apiService' });

const lambdaHandler = async (
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  tracer.putAnnotation('path', event.path);
  tracer.putAnnotation('method', event.httpMethod);

  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Hello World' })
  };
};

export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));

Middleware Installation

To use the Tracer middleware, you need to install Middy:

npm install @middy/core

Middy is specified as an optional peer dependency with version compatibility:

  • Compatible Versions: 4.x, 5.x, or 6.x

Middleware vs Decorator

Use Middleware when:

  • Using function-based handlers
  • Integrating with other Middy middleware
  • Prefer functional programming style

Use Decorators when:

  • Using class-based handlers
  • Want to trace multiple methods in a class
  • Prefer object-oriented programming style

See Decorator-based Tracing for decorator usage.