Skip to content

Commit 5a61bba

Browse files
committed
docs(maintenance): create upgrade guide
1 parent b387926 commit 5a61bba

File tree

1 file changed

+187
-2
lines changed

1 file changed

+187
-2
lines changed

Diff for: docs/upgrade.md

+187-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,190 @@ title: Upgrade guide
33
description: Guide to update between major Powertools for AWS Lambda (TypeScript) versions
44
---
55

6-
!!! warning
7-
This guide is a work in progress. We'll update it as we get closer to the 2.0 release. If you have any questions, or want to follow the progress, please join the discussion on the [GitHub issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/1714).
6+
## Migrate from v1 to v2
7+
8+
We've made targeted breaking changes to make your transition to v2 as smooth as possible while still providing you with the most up-to-date features and patterns. This guide will help you migrate your existing codebase to v2.
9+
10+
### Quick summary
11+
12+
| Area | Change | Code change required |
13+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- |
14+
| **ES Modules support** | TBD | - |
15+
| **Middy.js middleware imports** | Updated import path for Middy.js middlewares to leverage subpath exports - i.e. `@aws-lambda-powertools/tracer/middleware`. | Yes |
16+
| **Types imports** | Updated import path for TypeScript types to leverage subpath exports - i.e. `@aws-lambda-powertools/logger/types`. | Yes |
17+
| **Logger - log sampling** | Changed implementation of [log sampling](./core/logger.md#sampling-logs) to dynamically switch log level to `DEBUG` on a percentage of requests. | - |
18+
| **Logger - Custom Log Formatter** | Updated [custom log formatter](#custom-log-formatter) to include additional persistent attributes along with standard structured keys. | Yes |
19+
| **Logger & Tracer - helper functions** | Removed deprecated `createLogger` and `createTracer` helper functions in favor of direct instantiation. | Yes |
20+
21+
### First steps
22+
23+
Before you start, we suggest making a copy of your current working project or create a new git branch.
24+
25+
1. Upgrade Node.js to v16 or higher, Node.js v20 is recommended.
26+
2. Ensure that you have the latest Powertools for AWS Lambda (TypeScript) version via [Lambda Layer](./index.md#lambda-layer) or npm.
27+
3. Review the following sections to confirm whether they apply to your codebase.
28+
29+
## ES Modules support
30+
31+
TBD
32+
33+
## Scoped imports
34+
35+
### Middy.js middleware imports
36+
37+
Code changes are required only if you're using Middy.js middlewares, however this update benefits especially those who are **not** using Middy.js middlewares due to less code being imported and bundled in your Lambda function.
38+
39+
In v1, you could importing Middy.js middlewares in your codebase directly from the default export of a package. For example, to import the `injectLambdaContext` middleware for Logger, you would import it from `@aws-lambda-powertools/logger`.
40+
41+
With v2, we've added support for subpath exports. This means that you can now import Middy.js middlewares directly from a well-known path, i.e. `@aws-lambda-powertools/logger/middleware`. This allows you to import the middleware only when you need it, instead of requiring it and having it bundled in your Lambda function when you import the package.
42+
43+
### Types imports
44+
45+
In v1, importing TypeScript types in your codebase required you to be aware of the underlying directory structure of the Powertools for AWS Lambda (TypeScript) package. For example, to import a type from the `@aws-lambda-powertools/logger` package, you would need to import it from `@aws-lambda-powertools/logger/lib/types`.
46+
47+
Starting with v2, we've added support for subpath exports. This means that you can now import types directly from a well-known path, i.e. `@aws-lambda-powertools/logger/types`. This makes it easier and cleaner to import types in your codebase and removes the likelihood of breaking changes in the future.
48+
49+
## Logger
50+
51+
### Log sampling
52+
53+
This only applies if you're using the [log sampling](./core/logger.md#sampling-logs) feature in your codebase.
54+
55+
In v1, the `sampleRateValue` attribute could be set to a value between 0 and 1 when instantiating the `Logger` class. This value was used to determine the percentage of requests that would print logs at any log level regardless of the log level set in the `Logger` class.
56+
57+
For example, by setting the sample rate to 0.5 together with log level `ERROR`, roughly 50% of your Lambda invocations would print all the log items, including the `debug`, `info`, and `warn` ones.
58+
59+
```typescript
60+
import { Logger } from '@aws-lambda-powertools/logger';
61+
62+
const logger = new Logger({
63+
logLevel: 'ERROR',
64+
sampleRateValue: 0.5,
65+
});
66+
67+
export const handler = async () => {
68+
// This log item (equal to log level 'ERROR') will be printed to standard output
69+
// in all Lambda invocations
70+
logger.error('This is an ERROR log');
71+
72+
// These log items (below the log level 'ERROR') have ~50% chance
73+
// of being printed in a Lambda invocation
74+
logger.debug('This is a DEBUG log that has 50% chance of being printed');
75+
logger.info('This is an INFO log that has 50% chance of being printed');
76+
logger.warn('This is a WARN log that has 50% chance of being printed');
77+
};
78+
```
79+
80+
In v2, the `sampleRateValue` attribute is now used to determine the approximate percentage of requests that will have their log level switched to `DEBUG`. This means that the log level set in the `Logger` class will be used for all Lambda invocations, but for a percentage of them, the log level will be switched to `DEBUG` and all log items will be printed to standard output.
81+
82+
With this new behavior, you should see roughly the same number of log items printed to standard output as in v1, however, the implementation and logic is now in line with other runtimes of Powertools for AWS Lambda like Python, Java, and .NET.
83+
84+
### Custom log formatter
85+
86+
This only applies if you're using [a custom log formatter](./core/logger.md#custom-log-formatter-bring-your-own-formatter) to customize the log output.
87+
88+
Previously, the `formatAttributes` method was called with a single argument `attributes` of type `UnformattedAttributes`. This object contained all the [standard structured keys](./core/logger.md#standard-structured-keys) and values managed by Powertools for AWS Lambda (TypeScript). The method returned a plain object with the keys and values you wanted to include in the log output.
89+
90+
```typescript hl_lines="5 8"
91+
import { LogFormatter } from '@aws-lambda-powertools/logger';
92+
import {
93+
LogAttributes,
94+
UnformattedAttributes,
95+
} from '@aws-lambda-powertools/logger/lib/types';
96+
97+
class MyCompanyLogFormatter extends LogFormatter {
98+
public formatAttributes(attributes: UnformattedAttributes): LogAttributes {
99+
return {
100+
message: attributes.message,
101+
service: attributes.serviceName,
102+
environment: attributes.environment,
103+
awsRegion: attributes.awsRegion,
104+
correlationIds: {
105+
awsRequestId: attributes.lambdaContext?.awsRequestId,
106+
xRayTraceId: attributes.xRayTraceId,
107+
},
108+
lambdaFunction: {
109+
name: attributes.lambdaContext?.functionName,
110+
arn: attributes.lambdaContext?.invokedFunctionArn,
111+
memoryLimitInMB: attributes.lambdaContext?.memoryLimitInMB,
112+
version: attributes.lambdaContext?.functionVersion,
113+
coldStart: attributes.lambdaContext?.coldStart,
114+
},
115+
logLevel: attributes.logLevel,
116+
timestamp: this.formatTimestamp(attributes.timestamp),
117+
logger: {
118+
sampleRateValue: attributes.sampleRateValue,
119+
},
120+
};
121+
}
122+
}
123+
124+
export { MyCompanyLogFormatter };
125+
```
126+
127+
In v2, the `formatAttributes` method is instead called with two arguments `attributes` and `additionalLogAttributes`. The `attributes` argument is the same as in v1, but the `additionalLogAttributes` argument is a plain object containing any [additional attributes you might have added](./core/logger.md#appending-persistent-additional-log-keys-and-values) to your logger. The method returns a `LogItem` object that contains all the attributes you want to include in the log output.
128+
129+
```typescript hl_lines="1-2 5-8"
130+
import { LogFormatter, LogItem } from '@aws-lambda-powertools/logger';
131+
import type { LogAttributes, UnformattedAttributes } from '@aws-lambda-powertools/logger/types';
132+
133+
class MyCompanyLogFormatter extends LogFormatter {
134+
public formatAttributes(
135+
attributes: UnformattedAttributes,
136+
additionalLogAttributes: LogAttributes
137+
): LogItem {
138+
const baseAttributes = {
139+
message: attributes.message,
140+
service: attributes.serviceName,
141+
environment: attributes.environment,
142+
awsRegion: attributes.awsRegion,
143+
correlationIds: {
144+
awsRequestId: attributes.lambdaContext?.awsRequestId,
145+
xRayTraceId: attributes.xRayTraceId,
146+
},
147+
lambdaFunction: {
148+
name: attributes.lambdaContext?.functionName,
149+
arn: attributes.lambdaContext?.invokedFunctionArn,
150+
memoryLimitInMB: attributes.lambdaContext?.memoryLimitInMB,
151+
version: attributes.lambdaContext?.functionVersion,
152+
coldStart: attributes.lambdaContext?.coldStart,
153+
},
154+
logLevel: attributes.logLevel,
155+
timestamp: this.formatTimestamp(attributes.timestamp),
156+
logger: {
157+
sampleRateValue: attributes.sampleRateValue,
158+
},
159+
};
160+
// Create a new LogItem with the base attributes
161+
const logItem = new LogItem({ attributes: baseAttributes });
162+
// Merge additional attributes
163+
logItem.addAttributes(additionalLogAttributes);
164+
165+
return logItem;
166+
}
167+
}
168+
169+
export { MyCompanyLogFormatter };
170+
```
171+
172+
## Helper functions
173+
174+
We removed the deprecated `createLogger` and `createTracer` heper functions.
175+
176+
```typescript
177+
import { createLogger } from '@aws-lambda-powertools/logger';
178+
import { createTracer } from '@aws-lambda-powertools/tracer';
179+
180+
const logger = createLogger({ logLevel: 'info' });
181+
const tracer = createTracer({ serviceName: 'my-service' });
182+
```
183+
184+
You can migrate to instantiating the `Logger` and `Tracer` classes directly with no additional changes.
185+
186+
```typescript
187+
import { Logger } from '@aws-lambda-powertools/logger';
188+
import { Tracer } from '@aws-lambda-powertools/tracer';
189+
190+
const logger = new Logger({ logLevel: 'info' });
191+
const tracer = new Tracer({ serviceName: 'my-service' });
192+
```

0 commit comments

Comments
 (0)