@aws-lambda-powertools/tracer
Version:
The tracer package for the Powertools for AWS Lambda (TypeScript) library
533 lines • 20 kB
TypeScript
import { Utility } from '@aws-lambda-powertools/commons';
import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { ProviderServiceInterface } from './types/ProviderService.js';
import type { AnyClass, CaptureLambdaHandlerOptions, CaptureMethodOptions, MethodDecorator, TracerInterface, TracerOptions } from './types/Tracer.js';
/**
* ## Intro
* Tracer is an opinionated thin wrapper for [AWS X-Ray SDK for Node.js](https://github.com/aws/aws-xray-sdk-node).
*
* Tracing data can be visualized through AWS X-Ray Console.
*
* ## Key features
* * Auto capture cold start as annotation, and responses or full exceptions as metadata
* * Auto-disable when not running in AWS Lambda environment
* * Automatically trace HTTP(s) clients and generate segments for each request
* * Support tracing functions via decorators, middleware, and manual instrumentation
* * Support tracing AWS SDK v2 and v3 via AWS X-Ray SDK for Node.js
*
* ## Usage
*
* For more usage examples, see [our documentation](https://docs.powertools.aws.dev/lambda/typescript/latest/core/tracer/).
*
* ### Functions usage with middleware
*
* If you use function-based Lambda handlers you can use the {@link Tracer.captureLambdaHandler} middy middleware to automatically:
* * handle the subsegment lifecycle
* * add the `ServiceName` and `ColdStart` annotations
* * add the function response as metadata
* * add the function error as metadata (if any)
*
* @example
* ```typescript
* 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) => {
* ...
* };
*
* export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));
* ```
*
* ### Object oriented usage with decorators
*
* If instead you use TypeScript Classes to wrap your Lambda handler you can use the {@link Tracer.captureLambdaHandler} decorator to automatically:
* * handle the subsegment lifecycle
* * add the `ServiceName` and `ColdStart` annotations
* * add the function response as metadata
* * add the function error as metadata (if any)
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
* import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* class Lambda implements LambdaInterface {
* @tracer.captureLambdaHandler()
* public handler(_event: unknown, _context: unknown) {
* ...
* }
* }
*
* const handlerClass = new Lambda();
* export const handler = handlerClass.handler.bind(handlerClass);
* ```
*
* ### Functions usage with manual instrumentation
*
* If you prefer to manually instrument your Lambda handler you can use the methods in the tracer class directly.
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async (_event: unknown, _context: unknown) => {
* const segment = tracer.getSegment(); // This is the facade segment (the one that is created by AWS Lambda)
* // Create subsegment for the function & set it as active
* const subsegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
* tracer.setSegment(subsegment);
*
* // Annotate the subsegment with the cold start & serviceName
* tracer.annotateColdStart();
* tracer.addServiceNameAnnotation();
*
* let res;
* try {
* // ... your own logic goes here
* // Add the response as metadata
* tracer.addResponseAsMetadata(res, process.env._HANDLER);
* } catch (err) {
* // Add the error as metadata
* tracer.addErrorAsMetadata(err as Error);
* throw err;
* } finally {
* // Close the subsegment
* subsegment.close();
* // Set the facade segment as active again
* tracer.setSegment(segment);
* }
*
* return res;
* }
* ```
*/
declare class Tracer extends Utility implements TracerInterface {
/**
* The provider service interface used by the Tracer.
* This interface defines the methods and properties that a provider service must implement.
*/
provider: ProviderServiceInterface;
/**
* Flag indicating whether to capture errors.
* This is used to determine if errors should be added to the trace as metadata.
*
* @default true
*/
private captureError;
/**
* Flag indicating whether to capture HTTP(s) requests.
* @default true
*/
private captureHTTPsRequests;
/**
* Flag indicating whether to capture response data.
* @default true
*/
private captureResponse;
/**
* The custom configuration service used by the Tracer.
*/
private customConfigService?;
/**
* The environment variables service used by the Tracer, is always initialized in the constructor in setOptions().
*/
private envVarsService;
/**
* The name of the service, is always initialized in the constructor in setOptions().
*/
private serviceName;
/**
* Flag indicating whether tracing is enabled.
* @default true
*/
private tracingEnabled;
constructor(options?: TracerOptions);
/**
* Add an error to the current segment or subsegment as metadata.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-errors
*
* @param error - Error to serialize as metadata
* @param [remote] - Whether the error was thrown by a remote service. Defaults to `false`
*/
addErrorAsMetadata(error: Error, remote?: boolean): void;
/**
* Add response data to the current segment or subsegment as metadata.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-annotations
*
* @param data - Data to serialize as metadata
* @param methodName - Name of the method that is being traced
*/
addResponseAsMetadata(data?: unknown, methodName?: string): void;
/**
* Add service name to the current segment or subsegment as annotation.
*/
addServiceNameAnnotation(): void;
/**
* Add ColdStart annotation to the current segment or subsegment.
*
* If Tracer has been initialized outside the Lambda handler then the same instance
* of Tracer will be reused throughout the lifecycle of that same Lambda execution environment
* and this method will annotate `ColdStart: false` after the first invocation.
*
* @see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html
*/
annotateColdStart(): void;
/**
* Patch all AWS SDK v2 clients and create traces when your application makes calls to AWS services.
*
* If you want to patch a specific client use {@link captureAWSClient} and if you are using AWS SDK v3 use {@link captureAWSv3Client} instead.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-awssdkclients.html
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
* const AWS = tracer.captureAWS(require('aws-sdk'));
*
* export const handler = async (_event: unknown, _context: unknown) => {
* ...
* }
* ```
*
* @deprecated Use {@link captureAWSv3Client} instead.
* @param aws - AWS SDK v2 import
*/
captureAWS<T>(aws: T): T;
/**
* Patch a specific AWS SDK v2 client and create traces when your application makes calls to that AWS service.
*
* If you want to patch all clients use {@link captureAWS} and if you are using AWS SDK v3 use {@link captureAWSv3Client} instead.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-awssdkclients.html
*
* @example
* ```typescript
* import { S3 } from 'aws-sdk';
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
* const s3 = tracer.captureAWSClient(new S3({ apiVersion: '2006-03-01' }));
*
* export const handler = async (_event: unknown, _context: unknown) => {
* ...
* }
* ```
* @deprecated Use {@link captureAWSv3Client} instead.
* @param service - AWS SDK v2 client
*/
captureAWSClient<T>(service: T): T;
/**
* Patch an AWS SDK v3 client and create traces when your application makes calls to that AWS service.
*
* If you are using AWS SDK v2 use {@link captureAWSClient} instead.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-awssdkclients.html
*
* @example
* ```typescript
* import { S3Client } from '@aws-sdk/client-s3';
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
* const client = new S3Client({});
* tracer.captureAWSv3Client(client);
*
* export const handler = async (_event: unknown, _context: unknown) => {
* ...
* }
* ```
*
* @param service - AWS SDK v3 client
*/
captureAWSv3Client<T>(service: T): T;
/**
* A decorator automating capture of metadata and annotations on segments or subsegments for a Lambda Handler.
*
* Using this decorator on your handler function will automatically:
* * handle the subsegment lifecycle
* * add the `ColdStart` annotation
* * add the function response as metadata
* * add the function error as metadata (if any)
*
* Note: Currently TypeScript only supports decorators on classes and methods. If you are using the
* function syntax, you should use the middleware instead.
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
* import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* class Lambda implements LambdaInterface {
* @tracer.captureLambdaHandler()
* public handler(_event: unknown, _context: unknown) {
* // ...
* }
* }
*
* const handlerClass = new Lambda();
* export const handler = handlerClass.handler.bind(handlerClass);
* ```
*
* @param options - (_optional_) Options for the decorator
*/
captureLambdaHandler(options?: CaptureLambdaHandlerOptions): HandlerMethodDecorator;
/**
* A decorator automating capture of metadata and annotations on segments or subsegments for an arbitrary function.
*
* Using this decorator on your function will automatically:
* * handle the subsegment lifecycle
* * add the function response as metadata
* * add the function error as metadata (if any)
*
* Note: Currently TypeScript only supports decorators on classes and methods. If you are using the
* function syntax, you should use the middleware instead.
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
* import { LambdaInterface } from '@aws-lambda-powertools/commons';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* class Lambda implements LambdaInterface {
* @tracer.captureMethod()
* public myMethod(param: string) {
* // ...
* }
*
* public handler(_event: unknown, _context: unknown) {
* this.myMethod('foo');
* }
* }
*
* const handlerClass = new Lambda();
* export const handler = handlerClass.handler.bind(handlerClass);;
* ```
*
* @param options - (_optional_) Options for the decorator
*/
captureMethod<T extends AnyClass>(options?: CaptureMethodOptions): MethodDecorator<T>;
/**
* Get the current root AWS X-Ray trace id.
*
* Utility method that returns the current AWS X-Ray Root trace id. Useful as correlation id for downstream processes.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-traces
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async () => {
* try {
* ...
* } catch (err) {
* const rootTraceId = tracer.getRootXrayTraceId();
*
* // Example of returning an error response
* return {
* statusCode: 500,
* // Include the rootTraceId in the response so we can show a "contact support" button that
* // takes the customer to a customer service form with the trace as additional context.
* body: `Internal Error - Please contact support and quote the following id: ${rootTraceId}`,
* headers: { '_X_AMZN_TRACE_ID': rootTraceId },
* };
* }
* }
* ```
*/
getRootXrayTraceId(): string | undefined;
/**
* Get the active segment or subsegment (if any) in the current scope.
*
* Usually you won't need to call this method unless you are creating custom subsegments or using manual mode.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-segments
* @see https://docs.powertools.aws.dev/lambda/typescript/latest/core/tracer/#escape-hatch-mechanism
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async (_event: unknown, _context: unknown) => {
* const currentSegment = tracer.getSegment();
* ... // Do something with segment
* }
* ```
*/
getSegment(): Segment | Subsegment | undefined;
/**
* Get the current value of the AWS X-Ray Sampled flag.
*
* Utility method that returns the current AWS X-Ray Sampled flag.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-traces
*/
isTraceSampled(): boolean;
/**
* Get the current value of the `tracingEnabled` property.
*
* You can use this method during manual instrumentation to determine
* if tracer is currently enabled.
*/
isTracingEnabled(): boolean;
/**
* Add annotation to existing segment or subsegment.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-segment.html#xray-sdk-nodejs-segment-annotations
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async (_event: unknown, _context: unknown) => {
* tracer.putAnnotation('successfulBooking', true);
* }
* ```
*
* @param key - Annotation key
* @param value - Value for annotation
*/
putAnnotation(key: string, value: string | number | boolean): void;
/**
* Add metadata to existing segment or subsegment.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-segment.html#xray-sdk-nodejs-segment-metadata
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async (_event: unknown, _context: unknown) => {
* const res = someLogic();
* tracer.putMetadata('paymentResponse', res);
* }
* ```
*
* @param key - Metadata key
* @param value - Value for metadata
* @param namespace - Namespace that metadata will lie under, if none is passed it will use the serviceName
*/
putMetadata(key: string, value: unknown, namespace?: string | undefined): void;
/**
* Set the passed subsegment as the current active subsegment.
*
* If you are using a middleware or a decorator this is done automatically for you.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-subsegments.html
*
* @example
* ```typescript
* import { Tracer } from '@aws-lambda-powertools/tracer';
* import { Subsegment } from 'aws-xray-sdk-core';
*
* const tracer = new Tracer({ serviceName: 'serverlessAirline' });
*
* export const handler = async (_event: unknown, _context: unknown) => {
* const subsegment = new Subsegment('### foo.bar');
* tracer.setSegment(subsegment);
* }
* ```
*
* @param segment - Subsegment to set as the current segment
*/
setSegment(segment: Segment | Subsegment): void;
/**
* Getter for `customConfigService`.
* Used internally during initialization.
*/
private getCustomConfigService;
/**
* Get for `envVarsService`.
* Used internally during initialization.
*/
private getEnvVarsService;
/**
* Determine if we are running inside an Amplify CLI process.
* Used internally during initialization.
*/
private isAmplifyCli;
/**
* Determine if we are running in a Lambda execution environment.
* Used internally during initialization.
*/
private isLambdaExecutionEnv;
/**
* Determine if we are running inside a SAM CLI process.
* Used internally during initialization.
*/
private isLambdaSamCli;
/**
* Set `captureError` based on configuration passed and environment variables.
* Used internally during initialization.
*/
private setCaptureError;
/**
* Patch all HTTP(s) clients and create traces when your application makes calls outgoing calls.
*
* Calls using third-party HTTP request libraries, such as Axios, are supported as long as they use the native http
* module under the hood. Support for third-party HTTP request libraries is provided on a best effort basis.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-httpclients.html
*
* @param enabled - Whether or not to patch all HTTP clients
*/
private setCaptureHTTPsRequests;
/**
* Set `captureResponse` based on configuration passed and environment variables.
* Used internally during initialization.
*/
private setCaptureResponse;
/**
* Set `customConfigService` based on configuration passed.
* Used internally during initialization.
*
* @param customConfigService - Custom configuration service to use
*/
private setCustomConfigService;
/**
* Method that reconciles the configuration passed with the environment variables.
* Used internally during initialization.
*
* @param options - Configuration passed to the tracer
*/
private setOptions;
/**
* Set `customConfigService` based on configurations passed and environment variables.
* Used internally during initialization.
*
* @param serviceName - Name of the service to use
*/
private setServiceName;
/**
* Set `tracingEnabled` based on configurations passed and environment variables.
* Used internally during initialization.
*
* @param enabled - Whether or not tracing is enabled
*/
private setTracingEnabled;
}
export { Tracer };
//# sourceMappingURL=Tracer.d.ts.map