Skip to content

Commit b42c940

Browse files
committed
feat(logger): add removeKeys functionality
1 parent 25cf3ea commit b42c940

File tree

5 files changed

+145
-5
lines changed

5 files changed

+145
-5
lines changed

Diff for: docs/core/logger.md

+12-3
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,12 @@ You can append additional persistent keys and values in the logs generated durin
200200
* Via the Logger's `appendKeys` method, for all log items generated after calling this method
201201
* Passing them in the Logger's constructor
202202

203+
To remove the keys you added, you can use the `removeKeys` method.
204+
205+
203206
=== "handler.ts"
204207

205-
```typescript hl_lines="5-12 16-23"
208+
```typescript hl_lines="5-13 17-25 30"
206209
import { Logger } from '@aws-lambda-powertools/logger';
207210

208211
// Add persistent log keys via the constructor
@@ -213,7 +216,8 @@ You can append additional persistent keys and values in the logs generated durin
213216
logger: {
214217
name: '@aws-lambda-powertools/logger',
215218
version: '0.0.1',
216-
}
219+
},
220+
extra_key: "some-value"
217221
}
218222
});
219223

@@ -224,10 +228,14 @@ You can append additional persistent keys and values in the logs generated durin
224228
// logger: {
225229
// name: '@aws-lambda-powertools/logger',
226230
// version: '0.0.1',
227-
// }
231+
// },
232+
// extra_key: "some-value"
228233
// });
229234

230235
export const handler = async (_event: any, _context: any): Promise<unknown> => {
236+
237+
// If you don't want to log the "extra_key" attribute in your logs, you can remove it
238+
logger.removeKeys(["extra_key"])
231239

232240
// This info log will print all extra custom attributes added above
233241
// Extra attributes: logger object with name and version of the logger library, awsAccountId, awsRegion
@@ -271,6 +279,7 @@ You can append additional persistent keys and values in the logs generated durin
271279
}
272280
```
273281

282+
274283
!!! tip "Logger will automatically ignore any key with an `undefined` value"
275284

276285
### Appending additional data to a single log item

Diff for: packages/logger/src/Logger.ts

+24
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,20 @@ class Logger extends Utility implements ClassThatLogs {
178178
merge(this.persistentLogAttributes, attributes);
179179
}
180180

181+
/**
182+
* It removes attributes based on provided keys to all log items generated by this Logger instance.
183+
*
184+
* @param {string[]} keys
185+
* @returns {void}
186+
*/
187+
public removePersistentLogAttributes(keys: string[]): void {
188+
keys.forEach((key) => {
189+
if(this.persistentLogAttributes && key in this.persistentLogAttributes) {
190+
delete this.persistentLogAttributes[key];
191+
}
192+
})
193+
}
194+
181195
/**
182196
* Alias for addPersistentLogAttributes.
183197
*
@@ -188,6 +202,16 @@ class Logger extends Utility implements ClassThatLogs {
188202
this.addPersistentLogAttributes(attributes);
189203
}
190204

205+
/**
206+
* Alias for removePersistentLogAttributes.
207+
*
208+
* @param {string[]} keys
209+
* @returns {void}
210+
*/
211+
public removeKeys(keys: string[]): void {
212+
this.removePersistentLogAttributes(keys);
213+
}
214+
191215
/**
192216
* It creates a separate Logger instance, identical to the current one
193217
* It's possible to overwrite the new instance options by passing them.

Diff for: packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import middy from '@middy/core';
44

55
const PERSISTENT_KEY = process.env.PERSISTENT_KEY;
66
const PERSISTENT_VALUE = process.env.PERSISTENT_VALUE;
7+
const REMOVABLE_KEY = process.env.REMOVABLE_KEY;
8+
const REMOVABLE_VALUE = process.env.REMOVABLE_VALUE;
79
const ERROR_MSG = process.env.ERROR_MSG || 'error';
810
const SINGLE_LOG_ITEM_KEY = process.env.SINGLE_LOG_ITEM_KEY;
911
const SINGLE_LOG_ITEM_VALUE = process.env.SINGLE_LOG_ITEM_VALUE;
@@ -13,14 +15,16 @@ const ARBITRARY_OBJECT_DATA = process.env.ARBITRARY_OBJECT_DATA;
1315
const logger = new Logger({
1416
persistentLogAttributes: {
1517
[PERSISTENT_KEY]: PERSISTENT_VALUE,
18+
[REMOVABLE_KEY]: REMOVABLE_VALUE,
1619
},
1720
});
1821

1922
const testFunction = async (event: APIGatewayProxyEvent, context: Context): Promise<{requestId: string}> => {
2023
// Test feature 1: Log level filtering
2124
// Test feature 2: Context data
22-
// Test feature 3: Persistent additional log keys and value
25+
// Test feature 3: Add and remove persistent additional log keys and value
2326
// Test feature 4: X-Ray Trace ID injection
27+
logger.removeKeys([ REMOVABLE_KEY ]);
2428
logger.debug('##### This should not appear');
2529
logger.info('This is an INFO log with context and persistent key');
2630

Diff for: packages/logger/tests/e2e/basicFeatures.middy.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const lambdaFunctionCodeFile = 'basicFeatures.middy.test.FunctionCode.ts';
4343
// Text to be used by Logger in the Lambda function
4444
const PERSISTENT_KEY = 'persistentKey';
4545
const PERSISTENT_VALUE = `a persistent value that will be put in every log ${uuid}`;
46+
const REMOVABLE_KEY = "removableKey";
47+
const REMOVABLE_VALUE = "a persistent value that will be removed and not displayed in any log ${uuid}";
4648
const SINGLE_LOG_ITEM_KEY = `keyForSingleLogItem${uuid}`;
4749
const SINGLE_LOG_ITEM_VALUE = `a value for a single log item${uuid}`;
4850
const ERROR_MSG = `error-${uuid}`;
@@ -72,6 +74,8 @@ describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime}
7274
// Text to be used by Logger in the Lambda function
7375
PERSISTENT_KEY,
7476
PERSISTENT_VALUE,
77+
REMOVABLE_KEY,
78+
REMOVABLE_VALUE,
7579
SINGLE_LOG_ITEM_KEY,
7680
SINGLE_LOG_ITEM_VALUE,
7781
ERROR_MSG,
@@ -147,6 +151,14 @@ describe(`logger E2E tests basic functionalities (middy) for runtime: ${runtime}
147151
expect(message).toContain(`"${PERSISTENT_KEY}":"${PERSISTENT_VALUE}"`);
148152
}
149153
}, TEST_CASE_TIMEOUT);
154+
155+
it('should not contain persistent keys that were removed on runtime', async () => {
156+
const logMessages = invocationLogs[0].getFunctionLogs();
157+
158+
for (const message of logMessages) {
159+
expect(message).not.toContain(`"${REMOVABLE_KEY}":"${REMOVABLE_VALUE}"`);
160+
}
161+
}, TEST_CASE_TIMEOUT);
150162
});
151163

152164
describe('X-Ray Trace ID injection', () => {

Diff for: packages/logger/tests/unit/Logger.test.ts

+92-1
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ describe('Class: Logger', () => {
638638

639639
describe('Method: appendKeys', () => {
640640

641-
test('when called, populates the logger\'s propriety persistentLogAttributes ', () => {
641+
test('when called, it populates the logger\'s propriety persistentLogAttributes ', () => {
642642

643643
// Prepare
644644
const logger = new Logger();
@@ -704,6 +704,97 @@ describe('Class: Logger', () => {
704704
});
705705
});
706706

707+
describe('Method: removeKeys', () => {
708+
709+
test('when called, it removes keys from the logger\'s propriety persistentLogAttributes', () => {
710+
711+
// Prepare
712+
const logger = new Logger();
713+
logger.appendKeys({
714+
aws_account_id: '123456789012',
715+
aws_region: 'eu-west-1',
716+
logger: {
717+
name: 'aws-lambda-powertool-typescript',
718+
version: '0.2.4',
719+
},
720+
});
721+
722+
// Act
723+
logger.removeKeys(["aws_account_id", "aws_region"]);
724+
725+
// Assess
726+
expect(logger).toEqual(expect.objectContaining({
727+
persistentLogAttributes: {
728+
logger: {
729+
name: 'aws-lambda-powertool-typescript',
730+
version: '0.2.4',
731+
},
732+
},
733+
}));
734+
});
735+
736+
test('when called with non-existing keys, the logger\'s propriety persistentLogAttributes is not mutated and it does not throw an error', () => {
737+
738+
// Prepare
739+
const logger = new Logger();
740+
logger.appendKeys({
741+
aws_account_id: '123456789012',
742+
aws_region: 'eu-west-1',
743+
logger: {
744+
name: 'aws-lambda-powertool-typescript',
745+
version: '0.2.4',
746+
},
747+
});
748+
const loggerBeforeKeysAreRemoved = { ...logger };
749+
750+
// Act
751+
logger.removeKeys(["not_existing_key"]);
752+
753+
// Assess
754+
expect(logger).toEqual(loggerBeforeKeysAreRemoved);
755+
expect(logger).toEqual(expect.objectContaining({
756+
persistentLogAttributes: {
757+
aws_account_id: '123456789012',
758+
aws_region: 'eu-west-1',
759+
logger: {
760+
name: 'aws-lambda-powertool-typescript',
761+
version: '0.2.4',
762+
},
763+
},
764+
}));
765+
});
766+
767+
});
768+
769+
test('when called multiple times with the same keys, the outcome is the same', () => {
770+
771+
// Prepare
772+
const logger = new Logger();
773+
logger.appendKeys({
774+
aws_account_id: '123456789012',
775+
aws_region: 'eu-west-1',
776+
logger: {
777+
name: 'aws-lambda-powertool-typescript',
778+
version: '0.2.4',
779+
},
780+
});
781+
782+
// Act
783+
logger.removeKeys(["aws_account_id", "aws_region"]);
784+
logger.removeKeys(["aws_account_id", "aws_region"]);
785+
786+
// Assess
787+
expect(logger).toEqual(expect.objectContaining({
788+
persistentLogAttributes: {
789+
logger: {
790+
name: 'aws-lambda-powertool-typescript',
791+
version: '0.2.4',
792+
},
793+
},
794+
}));
795+
796+
});
797+
707798
describe('Method: injectLambdaContext', () => {
708799

709800
beforeEach(() => {

0 commit comments

Comments
 (0)