diff --git a/packages/tracer/README.md b/packages/tracer/README.md index c0e67baef0..1e0253454e 100644 --- a/packages/tracer/README.md +++ b/packages/tracer/README.md @@ -4,17 +4,11 @@ Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serve You can use the library in both TypeScript and JavaScript code bases. -> Also available in [Python](https://github.com/aws-powertools/powertools-lambda-python), [Java](https://github.com/aws-powertools/powertools-lambda-java), and [.NET](https://github.com/aws-powertools/powertools-lambda-dotnet). - -**[Documentation](https://docs.powertools.aws.dev/lambda/typescript/)** | **[npm](https://www.npmjs.com/org/aws-lambda-powertools)** | **[Roadmap](https://docs.powertools.aws.dev/lambda/typescript/latest/roadmap)** | **[Examples](https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/examples)** | **[Serverless TypeScript Demo](https://github.com/aws-samples/serverless-typescript-demo)** - -## Table of contents - -- [Features](#features) -- [Getting started](#getting-started) - - [Installation](#installation) - - [Examples](#examples) - - [Demo applications](#demo-applications) +- [Intro](#intro) +- [Usage](#usage) + - [Basic usage](#basic-usage) + - [Capture AWS SDK clients](#capture-aws-sdk-clients) + - [Add metadata and annotations](#add-metadata-and-annotations) - [Contribute](#contribute) - [Roadmap](#roadmap) - [Connect](#connect) @@ -22,60 +16,118 @@ You can use the library in both TypeScript and JavaScript code bases. - [Becoming a reference customer](#becoming-a-reference-customer) - [Sharing your work](#sharing-your-work) - [Using Lambda Layer](#using-lambda-layer) -- [Credits](#credits) - [License](#license) -## Features +## Intro + +The Tracer utility is an opinionated thin wrapper for [AWS X-Ray SDK for Node.js](https://github.com/aws/aws-xray-sdk-node), to automatically capture cold starts, trace HTTP(S) clients including `fetch` and generate segments and add metadata or annotations to traces. + +## Usage + +To get started, install the library by running: + +```sh +npm i @aws-lambda-powertools/tracer +``` + +### Basic usage + +Add `Tracer` to your Lambda handler as decorator: -- **[Tracer](https://docs.powertools.aws.dev/lambda/typescript/latest/core/tracer/)** - Utilities to trace Lambda function handlers, and both synchronous and asynchronous functions -- **[Logger](https://docs.powertools.aws.dev/lambda/typescript/latest/core/logger/)** - Structured logging made easier, and a middleware to enrich log items with key details of the Lambda context -- **[Metrics](https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics/)** - Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF) -- **[Parameters](https://docs.powertools.aws.dev/lambda/typescript/latest/utilities/parameters/)** - High-level functions to retrieve one or more parameters from AWS SSM, Secrets Manager, AppConfig, and DynamoDB +```ts +import type { LambdaInterface } from '@aws-lambda-powertools/commons/types'; +import { Tracer } from '@aws-lambda-powertools/tracer'; -## Getting started +const tracer = new Tracer({ serviceName: 'serverlessAirline' }); -Find the complete project's [documentation here](https://docs.powertools.aws.dev/lambda/typescript). +class Lambda implements LambdaInterface { + // Decorate your handler class method + @tracer.captureLambdaHandler() + public async handler(_event: unknown, _context: unknown): Promise { + tracer.getSegment(); + } +} -### Installation +const handlerClass = new Lambda(); +export const handler = handlerClass.handler.bind(handlerClass); +``` + +or using middy: + +```ts +import { Tracer } from '@aws-lambda-powertools/tracer'; +import { captureLambdaHandler } from '@aws-lambda-powertools/tracer/middleware'; +import middy from '@middy/core'; -The Powertools for AWS Lambda (TypeScript) utilities follow a modular approach, similar to the official [AWS SDK v3 for JavaScript](https://github.com/aws/aws-sdk-js-v3). -Each TypeScript utility is installed as standalone NPM package. +const tracer = new Tracer({ serviceName: 'serverlessAirline' }); -Install all three core utilities at once with this single command: +const lambdaHandler = async ( + _event: unknown, + _context: unknown +): Promise => { + tracer.putAnnotation('successfulBooking', true); +}; -```shell -npm install @aws-lambda-powertools/logger @aws-lambda-powertools/tracer @aws-lambda-powertools/metrics +// Wrap the handler with middy +export const handler = middy(lambdaHandler) + // Use the middleware by passing the Tracer instance as a parameter + .use(captureLambdaHandler(tracer)); ``` -Or refer to the installation guide of each utility: +### Capture AWS SDK clients + +To capture AWS SDK clients, you can use the `captureAWSv3Client` method: + +```ts +import { Tracer } from '@aws-lambda-powertools/tracer'; +import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager'; -πŸ‘‰ [Installation guide for the **Tracer** utility](https://docs.powertools.aws.dev/lambda/typescript/latest/core/tracer#getting-started) +const tracer = new Tracer({ serviceName: 'serverlessAirline' }); +// Instrument the AWS SDK client +const client = tracer.captureAWSv3Client(new SecretsManagerClient({})); -πŸ‘‰ [Installation guide for the **Logger** utility](https://docs.powertools.aws.dev/lambda/typescript/latest/core/logger#getting-started) +export default client; +``` + +### Add metadata and annotations -πŸ‘‰ [Installation guide for the **Metrics** utility](https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics#getting-started) +You can add metadata and annotations to trace: -πŸ‘‰ [Installation guide for the **Parameters** utility](https://docs.powertools.aws.dev/lambda/typescript/latest/utilities/parameters/#getting-started) +```ts -### Examples +import { Tracer } from '@aws-lambda-powertools/tracer'; -You can find examples of how to use Powertools for AWS Lambda (TypeScript) in the [examples](https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/examples/app) directory. The application is a simple REST API that can be deployed via either AWS CDK or AWS SAM. +const tracer = new Tracer({ serviceName: 'serverlessAirline' }); -### Demo applications +export const handler = async ( + _event: unknown, + _context: unknown +): Promise => { + const handlerSegment = tracer.getSegment()?.addNewSubsegment('### handler'); + handlerSegment && tracer.setSegment(handlerSegment); -The [Serverless TypeScript Demo](https://github.com/aws-samples/serverless-typescript-demo) shows how to use Powertools for AWS Lambda (TypeScript). -You can find instructions on how to deploy and load test this application in the [repository](https://github.com/aws-samples/serverless-typescript-demo). + tracer.putMetadata('paymentResponse', { + foo: 'bar', + }); + tracer.putAnnotation('successfulBooking', true); -The [AWS Lambda performance tuning](https://github.com/aws-samples/optimizations-for-lambda-functions) repository also uses Powertools for AWS Lambda (TypeScript) as well as demonstrating other performance tuning techniques for Lambda functions written in TypeScript. + handlerSegment?.close(); + handlerSegment && tracer.setSegment(handlerSegment?.parent); +}; +``` ## Contribute -If you are interested in contributing to this project, please refer to our [Contributing Guidelines](https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/CONTRIBUTING.md). +If you are interested in contributing to this project, please refer to +our [Contributing Guidelines](https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/CONTRIBUTING.md). ## Roadmap The roadmap of Powertools for AWS Lambda (TypeScript) is driven by customers’ demand. -Help us prioritize upcoming functionalities or utilities by [upvoting existing RFCs and feature requests](https://github.com/aws-powertools/powertools-lambda-typescript/issues), or [creating new ones](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose), in this GitHub repository. +Help us prioritize upcoming functionalities or utilities +by [upvoting existing RFCs and feature requests](https://github.com/aws-powertools/powertools-lambda-typescript/issues), +or [creating new ones](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose), in this GitHub +repository. ## Connect @@ -86,7 +138,10 @@ Help us prioritize upcoming functionalities or utilities by [upvoting existing R ### Becoming a reference customer -Knowing which companies are using this library is important to help prioritize the project internally. If your company is using Powertools for AWS Lambda (TypeScript), you can request to have your name and logo added to the README file by raising a [Support Powertools for AWS Lambda (TypeScript) (become a reference)](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E) issue. +Knowing which companies are using this library is important to help prioritize the project internally. If your company +is using Powertools for AWS Lambda (TypeScript), you can request to have your name and logo added to the README file by +raising a [Support Powertools for AWS Lambda (TypeScript) (become a reference)](https://s12d.com/become-reference-pt-ts) +issue. The following companies, among others, use Powertools: @@ -108,15 +163,16 @@ The following companies, among others, use Powertools: ### Sharing your work -Share what you did with Powertools for AWS Lambda (TypeScript) πŸ’žπŸ’ž. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools for AWS Lambda (TypeScript) [here](https://docs.powertools.aws.dev/lambda/typescript/latest/we_made_this). +Share what you did with Powertools for AWS Lambda (TypeScript) πŸ’žπŸ’ž. Blog post, workshops, presentation, sample apps and +others. Check out what the community has already shared about Powertools for AWS Lambda ( +TypeScript) [here](https://docs.powertools.aws.dev/lambda/typescript/latest/we_made_this). ### Using Lambda Layer -This helps us understand who uses Powertools for AWS Lambda (TypeScript) in a non-intrusive way, and helps us gain future investments for other Powertools for AWS Lambda languages. When [using Layers](#lambda-layers), you can add Powertools for AWS Lambda (TypeScript) as a dev dependency (or as part of your virtual env) to not impact the development process. - -## Credits - -Credits for the Powertools for AWS Lambda (TypeScript) idea go to [DAZN](https://github.com/getndazn) and their [DAZN Lambda Powertools](https://github.com/getndazn/dazn-lambda-powertools/). +This helps us understand who uses Powertools for AWS Lambda (TypeScript) in a non-intrusive way, and helps us gain +future investments for other Powertools for AWS Lambda languages. +When [using Layers](https://docs.powertools.aws.dev/lambda/typescript/latest/#lambda-layer), you can add Powertools as a +dev dependency to not impact the development process. ## License diff --git a/packages/tracer/src/Tracer.ts b/packages/tracer/src/Tracer.ts index 9b1cf24855..374c1359ce 100644 --- a/packages/tracer/src/Tracer.ts +++ b/packages/tracer/src/Tracer.ts @@ -40,7 +40,7 @@ const { Subsegment: XraySubsegment } = xraySdk; * * ### Functions usage with middleware * - * If you use function-based Lambda handlers you can use the [captureLambdaHandler()](./_aws_lambda_powertools_tracer.Tracer.html) middy middleware to automatically: + * 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 @@ -63,7 +63,7 @@ const { Subsegment: XraySubsegment } = xraySdk; * * ### Object oriented usage with decorators * - * If instead you use TypeScript Classes to wrap your Lambda handler you can use the [@tracer.captureLambdaHandler()](./_aws_lambda_powertools_tracer.Tracer.html#captureLambdaHandler) decorator to automatically: + * 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 @@ -128,22 +128,48 @@ const { Subsegment: XraySubsegment } = xraySdk; * ``` */ 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. + */ public 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 = true; - + /** + * Flag indicating whether to capture HTTP(s) requests. + * @default true + */ private captureHTTPsRequests = true; - + /** + * Flag indicating whether to capture response data. + * @default true + */ private captureResponse = true; - + /** + * The custom configuration service used by the Tracer. + */ private customConfigService?: ConfigServiceInterface; - // envVarsService is always initialized in the constructor in setOptions() + /** + * The environment variables service used by the Tracer, is always initialized in the constructor in setOptions(). + */ private envVarsService!: EnvironmentVariablesService; // serviceName is always initialized in the constructor in setOptions() + /** + * The name of the service, is always initialized in the constructor in setOptions(). + */ private serviceName!: string; - + /** + * Flag indicating whether tracing is enabled. + * @default true + */ private tracingEnabled = true; public constructor(options: TracerOptions = {}) { @@ -210,7 +236,6 @@ class Tracer extends Utility implements TracerInterface { /** * Add service name to the current segment or subsegment as annotation. - * */ public addServiceNameAnnotation(): void { if (!this.isTracingEnabled()) { @@ -255,7 +280,6 @@ class Tracer extends Utility implements TracerInterface { * * @deprecated Use {@link captureAWSv3Client} instead. * @param aws - AWS SDK v2 import - * @returns AWS - Instrumented AWS SDK */ public captureAWS(aws: T): T { if (!this.isTracingEnabled()) return aws; @@ -284,7 +308,6 @@ class Tracer extends Utility implements TracerInterface { * ``` * @deprecated Use {@link captureAWSv3Client} instead. * @param service - AWS SDK v2 client - * @returns service - Instrumented AWS SDK v2 client */ public captureAWSClient(service: T): T { if (!this.isTracingEnabled()) return service; @@ -327,7 +350,6 @@ class Tracer extends Utility implements TracerInterface { * ``` * * @param service - AWS SDK v3 client - * @returns service - Instrumented AWS SDK v3 client */ public captureAWSv3Client(service: T): T { if (!this.isTracingEnabled()) return service; @@ -365,7 +387,6 @@ class Tracer extends Utility implements TracerInterface { * export const handler = handlerClass.handler.bind(handlerClass); * ``` * - * @decorator Class * @param options - (_optional_) Options for the decorator */ public captureLambdaHandler( @@ -454,7 +475,6 @@ class Tracer extends Utility implements TracerInterface { * export const handler = handlerClass.handler.bind(handlerClass);; * ``` * - * @decorator Class * @param options - (_optional_) Options for the decorator */ public captureMethod( @@ -542,8 +562,6 @@ class Tracer extends Utility implements TracerInterface { * } * } * ``` - * - * @returns string - The root X-Ray trace id. */ public getRootXrayTraceId(): string | undefined { return this.envVarsService.getXrayTraceId(); @@ -568,8 +586,6 @@ class Tracer extends Utility implements TracerInterface { * ... // Do something with segment * } * ``` - * - * @returns The active segment or subsegment in the current scope. Will log a warning and return `undefined` if no segment is found. */ public getSegment(): Segment | Subsegment | undefined { if (!this.isTracingEnabled()) { @@ -591,8 +607,6 @@ class Tracer extends Utility implements TracerInterface { * 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 - * - * @returns boolean - `true` if the trace is sampled, `false` if tracing is disabled or the trace is not sampled. */ public isTraceSampled(): boolean { if (!this.isTracingEnabled()) return false; @@ -605,15 +619,13 @@ class Tracer extends Utility implements TracerInterface { * * You can use this method during manual instrumentation to determine * if tracer is currently enabled. - * - * @returns tracingEnabled - `true` if tracing is enabled, `false` otherwise. */ public isTracingEnabled(): boolean { return this.tracingEnabled; } /** - * Adds annotation to existing segment or subsegment. + * 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 * @@ -638,7 +650,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Adds metadata to existing segment or subsegment. + * 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 * @@ -669,7 +681,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Sets the passed subsegment as the current active subsegment. + * Set the passed subsegment as the current active subsegment. * * If you are using a middleware or a decorator this is done automatically for you. * @@ -705,7 +717,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Getter for `envVarsService`. + * Get for `envVarsService`. * Used internally during initialization. */ private getEnvVarsService(): EnvironmentVariablesService { @@ -740,7 +752,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter for `captureError` based on configuration passed and environment variables. + * Set `captureError` based on configuration passed and environment variables. * Used internally during initialization. */ private setCaptureError(): void { @@ -772,7 +784,6 @@ class Tracer extends Utility implements TracerInterface { * @see https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-httpclients.html * * @param enabled - Whether or not to patch all HTTP clients - * @returns void */ private setCaptureHTTPsRequests(enabled?: boolean): void { if (enabled !== undefined && !enabled) { @@ -801,7 +812,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter for `captureResponse` based on configuration passed and environment variables. + * Set `captureResponse` based on configuration passed and environment variables. * Used internally during initialization. */ private setCaptureResponse(): void { @@ -825,7 +836,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter for `customConfigService` based on configuration passed. + * Set `customConfigService` based on configuration passed. * Used internally during initialization. * * @param customConfigService - Custom configuration service to use @@ -839,7 +850,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter and initializer for `envVarsService`. + * Set and initialize `envVarsService`. * Used internally during initialization. */ private setEnvVarsService(): void { @@ -868,7 +879,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter for `customConfigService` based on configurations passed and environment variables. + * Set `customConfigService` based on configurations passed and environment variables. * Used internally during initialization. * * @param serviceName - Name of the service to use @@ -900,7 +911,7 @@ class Tracer extends Utility implements TracerInterface { } /** - * Setter for `tracingEnabled` based on configurations passed and environment variables. + * Set `tracingEnabled` based on configurations passed and environment variables. * Used internally during initialization. * * @param enabled - Whether or not tracing is enabled diff --git a/packages/tracer/typedoc.json b/packages/tracer/typedoc.json index ecfe51c09b..7df20e3456 100644 --- a/packages/tracer/typedoc.json +++ b/packages/tracer/typedoc.json @@ -1,5 +1,9 @@ { "extends": ["../../typedoc.base.json"], - "entryPoints": ["./src/index.ts", "./src/types/index.ts"], + "entryPoints": [ + "./src/index.ts", + "./src/types/index.ts", + "./src/middleware/middy.ts" + ], "readme": "README.md" }