Skip to content

Commit

Permalink
docs(tracer): extract Tracer code snippets in separate files aws-powe…
Browse files Browse the repository at this point in the history
  • Loading branch information
niko-achilles committed Jan 11, 2023
1 parent 3ebc65e commit bbe8405
Show file tree
Hide file tree
Showing 19 changed files with 256 additions and 238 deletions.
256 changes: 18 additions & 238 deletions docs/core/tracer.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ The `Tracer` utility must always be instantiated outside of the Lambda handler.
=== "handler.ts"

```typescript hl_lines="1 3"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (_event, _context): Promise<void> => {
// ...
};
--8<-- "docs/snippets/tracer/basicUsage.ts"
```

### Utility settings
Expand All @@ -68,15 +62,7 @@ The `Tracer` utility is instantiated outside of the Lambda handler. In doing thi
=== "handler.ts"

```typescript hl_lines="1 4"
import { Tracer } from '@aws-lambda-powertools/tracer';

// Tracer parameter fetched from the environment variables (see template.yaml tab)
const tracer = new Tracer();

// You can also pass the parameter in the constructor
// const tracer = new Tracer({
// serviceName: 'serverlessAirline'
// });
--8<-- "docs/snippets/tracer/sam.ts"
```

=== "template.yml"
Expand Down Expand Up @@ -104,19 +90,7 @@ You can quickly start by importing the `Tracer` class, initialize it outside the
Learn more about [its usage and lifecycle in the official Middy documentation](https://middy.js.org/docs/intro/getting-started){target="_blank"}.

```typescript hl_lines="1-2 11 13"
import { Tracer, captureLambdaHandler } from '@aws-lambda-powertools/tracer';
import middy from '@middy/core'; // (1)

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

const lambdaHandler = async (_event: any, _context: any): Promise<void> => {
/* ... */
};

// Wrap the handler with middy
export const handler = middy(lambdaHandler)
// Use the middleware by passing the Tracer instance as a parameter
.use(captureLambdaHandler(tracer));
--8<-- "docs/snippets/tracer/middy.ts"
```

1. Using Middy for the first time? You can install Middy by running `npm i @middy/core`.
Expand All @@ -129,60 +103,15 @@ You can quickly start by importing the `Tracer` class, initialize it outside the
See the [official TypeScript documentation](https://www.typescriptlang.org/docs/handbook/decorators.html) for more details.

```typescript hl_lines="8"
import { Tracer } from '@aws-lambda-powertools/tracer';
import { LambdaInterface } from '@aws-lambda-powertools/commons';

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

class Lambda implements LambdaInterface {
// Decorate your handler class method
@tracer.captureLambdaHandler()
public async handler(_event: any, _context: any): Promise<void> {
/* ... */
}
}
const handlerClass = new Lambda();
export const handler = handlerClass.handler.bind(handlerClass); // (1)
--8<-- "docs/snippets/tracer/decorator.ts"
```

1. Binding your handler method allows your handler to access `this`.

=== "Manual"

```typescript hl_lines="6 8-9 12-13 19 22 26 28"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (_event: any, context: any): Promise<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 {
/* ... */
// 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 subsegment (the AWS Lambda one is closed automatically)
subsegment.close();
// Set back the facade segment as active again
tracer.setSegment(segment);
}

return res;
};
--8<-- "docs/snippets/tracer/manual.ts"
```


Expand All @@ -203,26 +132,13 @@ When using the `captureLambdaHandler` decorator or middleware, Tracer performs t
You can add annotations using `putAnnotation` method.

```typescript hl_lines="6"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (_event: any, _context: any): Promise<void> => {
tracer.putAnnotation('successfulBooking', true);
};
--8<-- "docs/snippets/tracer/putAnnotation.ts"
```
=== "Metadata"
You can add metadata using `putMetadata` method.

```typescript hl_lines="7"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (_event: any, _context: any): Promise<void> => {
const res; /* ... */
tracer.putMetadata('paymentResponse', res);
};
--8<-- "docs/snippets/tracer/putMetadata.ts"
```

<figure>
Expand All @@ -237,26 +153,7 @@ You can trace other Class methods using the `captureMethod` decorator or any arb
=== "Decorator"

```typescript hl_lines="8"
import { Tracer } from '@aws-lambda-powertools/tracer';
import { LambdaInterface } from '@aws-lambda-powertools/commons';

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

class Lambda implements LambdaInterface {
// Decorate your class method
@tracer.captureMethod() // (1)
public getChargeId(): string {
/* ... */
return 'foo bar';
}

public async handler(_event: any, _context: any): Promise<void> {
/* ... */
}
}
const handlerClass = new Lambda();
export const handler = handlerClass.handler.bind(handlerClass); // (2)
--8<-- "docs/snippets/tracer/captureMethodDecorator.ts"
```

1. You can set a custom name for the subsegment by passing `subSegmentName` to the decorator, like: `@tracer.captureMethod({ subSegmentName: '### myCustomMethod' })`.
Expand All @@ -265,40 +162,7 @@ You can trace other Class methods using the `captureMethod` decorator or any arb
=== "Manual"

```typescript hl_lines="6 8-9 15 18 23 25"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

const getChargeId = async (): Promise<unknown> => {
const parentSubsegment = tracer.getSegment(); // This is the subsegment currently active
// Create subsegment for the function & set it as active
const subsegment = parentSubsegment.addNewSubsegment(`### chargeId`);
tracer.setSegment(subsegment);

let res;
try {
/* ... */
// Add the response as metadata
tracer.addResponseAsMetadata(res, 'chargeId');
} catch (err) {
// Add the error as metadata
tracer.addErrorAsMetadata(err as Error);
throw err;
}

// Close subsegment (the AWS Lambda one is closed automatically)
subsegment.close();
// Set the facade segment as active again
tracer.setSegment(parentSubsegment);

return res;
};

export const handler = async (_event: any, _context: any): Promise<void> => {
const chargeId = getChargeId();
const payment = collectPayment(chargeId);
/* ... */
};
--8<-- "docs/snippets/tracer/captureMethodManual.ts"
```


Expand All @@ -314,11 +178,7 @@ You can patch any AWS SDK clients by calling the `captureAWSv3Client` method:
=== "index.ts"

```typescript hl_lines="5"
import { S3Client } from '@aws-sdk/client-s3';
import { Tracer } from '@aws-lambda-powertools/tracer';

const tracer = new Tracer({ serviceName: 'serverlessAirline' });
const client = tracer.captureAWSv3Client(new S3Client({}));
--8<-- "docs/snippets/tracer/captureAWSv3.ts"
```

!!! info
Expand All @@ -329,22 +189,15 @@ You can patch all AWS SDK v2 clients by calling the `captureAWS` method:
=== "index.ts"

```typescript hl_lines="4"
import { Tracer } from '@aws-lambda-powertools/tracer';

const tracer = new Tracer({ serviceName: 'serverlessAirline' });
const AWS = tracer.captureAWS(require('aws-sdk'));
--8<-- "docs/snippets/tracer/captureAWSAll.ts"
```

If you're looking to shave a few microseconds, or milliseconds depending on your function memory configuration, you can patch only specific AWS SDK v2 clients using `captureAWSClient`:

=== "index.ts"

```typescript hl_lines="5"
import { S3 } from 'aws-sdk';
import { Tracer } from '@aws-lambda-powertools/tracer';

const tracer = new Tracer({ serviceName: 'serverlessAirline' });
const s3 = tracer.captureAWSClient(new S3());
--8<-- "docs/snippets/tracer/captureAWS.ts"
```

### Tracing HTTP requests
Expand All @@ -360,14 +213,7 @@ You can opt-out from this feature by setting the **`POWERTOOLS_TRACER_CAPTURE_HT
=== "index.ts"

```typescript hl_lines="2 7"
import { Tracer } from '@aws-lambda-powertools/tracer';
import axios from 'axios'; // (1)

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

export const handler = async (event: unknown, context: Context): Promise<void> => {
await axios.get('https://httpbin.org/status/200');
};
--8<-- "docs/snippets/tracer/captureHTTP.ts"
```

1. You can install the [axios](https://www.npmjs.com/package/axios) package using `npm i axios`
Expand Down Expand Up @@ -418,62 +264,19 @@ Alternatively, use the `captureResponse: false` option in both `tracer.captureLa
=== "method.ts"

```typescript hl_lines="6"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

class Lambda implements LambdaInterface {
@tracer.captureMethod({ captureResult: false })
public getChargeId(): string {
/* ... */
return 'foo bar';
}

public async handler(_event: any, _context: any): Promise<void> {
/* ... */
}
}

const handlerClass = new Lambda();
export const handler = handlerClass.handler.bind(handlerClass);
--8<-- "docs/snippets/tracer/disableCaptureResponseMethod.ts"
```

=== "handler.ts"

```typescript hl_lines="7"
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.captureLambdaHandler({ captureResponse: false })
async handler(_event: any, _context: any): Promise<void> {
/* ... */
}
}

const handlerClass = new Lambda();
export const handler = handlerClass.handler.bind(handlerClass);
--8<-- "docs/snippets/tracer/disableCaptureResponseHandler.ts"
```

=== "middy.ts"

```typescript hl_lines="14"
import { Tracer, captureLambdaHandler } from '@aws-lambda-powertools/tracer';
import middy from '@middy/core';

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

const lambdaHandler = async (_event: any, _context: any): Promise<void> => {
/* ... */
};

// Wrap the handler with middy
export const handler = middy(lambdaHandler)
// Use the middleware by passing the Tracer instance as a parameter,
// but specify the captureResponse option as false.
.use(captureLambdaHandler(tracer, { captureResponse: false }));
--8<-- "docs/snippets/tracer/disableCaptureResponseMiddy.ts"
```

### Disabling errors auto-capture
Expand All @@ -496,24 +299,7 @@ Tracer exposes a `getRootXrayTraceId()` method that allows you to retrieve the [
=== "index.ts"

```typescript hl_lines="9"
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (event: unknown, context: Context): Promise<void> => {
try {
...
} catch (err) {
const rootTraceId = tracer.getRootXrayTraceId();

// Example of returning an error response
return {
statusCode: 500,
body: `Internal Error - Please contact support and quote the following id: ${rootTraceId}`,
headers: { '_X_AMZN_TRACE_ID': rootTraceId },
};
}
};
--8<-- "docs/snippets/tracer/accessRootTraceId.ts"
```

### Escape hatch mechanism
Expand All @@ -525,13 +311,7 @@ This is useful when you need a feature available in X-Ray that is not available
=== "index.ts"

```typescript hl_lines="7"
import { Logger } from '@aws-lambda-powertools/logger';
import { Tracer } from '@aws-lambda-powertools/tracer';

const serviceName = 'serverlessAirline';
const logger = new Logger({ serviceName: serviceName });
const tracer = new Tracer({ serviceName: serviceName });
tracer.provider.setLogger(logger);
--8<-- "docs/snippets/tracer/escapeHatch.ts"
```

## Testing your code
Expand Down
18 changes: 18 additions & 0 deletions docs/snippets/tracer/accessRootTraceId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Tracer } from '@aws-lambda-powertools/tracer';

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

export const handler = async (event: unknown, context: Context): Promise<void> => {
try {

} catch (err) {
const rootTraceId = tracer.getRootXrayTraceId();

// Example of returning an error response
return {
statusCode: 500,
body: `Internal Error - Please contact support and quote the following id: ${rootTraceId}`,
headers: { '_X_AMZN_TRACE_ID': rootTraceId },
};
}
};
Loading

0 comments on commit bbe8405

Please sign in to comment.