Skip to content

Commit c99714f

Browse files
authored
tests(logger): revisited integration tests (aws-powertools#1342)
* tests: basicFeatures * tests: logEvent * tests: childLogger * tests: sampleRate
1 parent 487298f commit c99714f

11 files changed

+403
-274
lines changed

packages/commons/tests/utils/InvocationLogs.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,35 +69,41 @@ export class InvocationLogs {
6969
* @returns {number} index of the log that contains END RequestId
7070
*/
7171
public static getEndLogIndex(logs: string[]): number {
72-
return logs.findIndex((log) => log.includes('END RequestId'));
72+
return logs.findIndex((log) => log.startsWith('END RequestId'));
7373
}
7474

7575
/**
76-
* Return only logs from function, exclude START, END, REPORT, and XRay log generated by Lambda service
77-
* @param levelToFilter level to filter
78-
* @returns Array of function logs
76+
* Return only logs from function, exclude START, END, REPORT,
77+
* and X-Ray log generated by the Lambda service.
78+
*
79+
* @param {LEVEL} [levelToFilter] - Level to filter the logs
80+
* @returns Array of function logs, filtered by level if provided
7981
*/
8082
public getFunctionLogs(levelToFilter?: LEVEL): string[] {
83+
const startLogIndex = InvocationLogs.getStartLogIndex(this.logs);
8184
const endLogIndex = InvocationLogs.getEndLogIndex(this.logs);
82-
let filteredLogs = this.logs.slice(1, endLogIndex);
85+
let filteredLogs = this.logs.slice(startLogIndex + 1, endLogIndex);
8386

8487
if (levelToFilter) {
8588
filteredLogs = filteredLogs.filter((log) => {
8689
try {
87-
const parsedLog = JSON.parse(log);
88-
if (parsedLog.level == levelToFilter) return parsedLog;
89-
else return;
90+
const parsedLog = InvocationLogs.parseFunctionLog(log);
91+
92+
return parsedLog.level == levelToFilter;
9093
} catch (error) {
9194
// If log is not from structured logging : such as metrics one.
92-
if (log.split('\t')[2] == levelToFilter) return log;
93-
else return;
95+
return log.split('\t')[2] == levelToFilter;
9496
}
9597
});
9698
}
9799

98100
return filteredLogs;
99101
}
100102

103+
public static getStartLogIndex(logs: string[]): number {
104+
return logs.findIndex((log) => log.startsWith('START RequestId'));
105+
}
106+
101107
/**
102108
* Each of log message contains a JSON with the structured Log object (e.g. {\"cold_start\":true, ..})
103109
* @param log

packages/logger/tests/e2e/basicFeatures.middy.test.FunctionCode.ts

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,66 @@
11
import { injectLambdaContext, Logger } from '../../src';
22
import { Context, APIGatewayAuthorizerResult } from 'aws-lambda';
3+
import { TestEvent, TestOutput } from '../helpers/types';
34
import middy from '@middy/core';
45

5-
const PERSISTENT_KEY = process.env.PERSISTENT_KEY;
6-
const PERSISTENT_KEY_FIRST_INVOCATION_ONLY = process.env.PERSISTENT_KEY_FIRST_INVOCATION_ONLY;
7-
const PERSISTENT_VALUE = process.env.PERSISTENT_VALUE;
8-
const REMOVABLE_KEY = process.env.REMOVABLE_KEY;
9-
const REMOVABLE_VALUE = process.env.REMOVABLE_VALUE;
6+
const PERSISTENT_KEY = process.env.PERSISTENT_KEY || 'persistentKey';
7+
const PERSISTENT_VALUE = process.env.PERSISTENT_VALUE || 'persistentValue';
8+
const REMOVABLE_KEY = process.env.REMOVABLE_KEY || 'removableKey';
9+
const REMOVABLE_VALUE = process.env.REMOVABLE_VALUE || 'remvovableValue';
1010
const ERROR_MSG = process.env.ERROR_MSG || 'error';
11-
const SINGLE_LOG_ITEM_KEY = process.env.SINGLE_LOG_ITEM_KEY;
12-
const SINGLE_LOG_ITEM_VALUE = process.env.SINGLE_LOG_ITEM_VALUE;
13-
const ARBITRARY_OBJECT_KEY = process.env.ARBITRARY_OBJECT_KEY;
14-
const ARBITRARY_OBJECT_DATA = process.env.ARBITRARY_OBJECT_DATA;
15-
16-
type LambdaEvent = {
17-
invocation: number
18-
};
11+
const RUNTIME_ADDED_KEY = process.env.RUNTIME_ADDED_KEY || 'runtimeAddedKey';
12+
const SINGLE_LOG_ITEM_KEY = process.env.SINGLE_LOG_ITEM_KEY || 'keyForSingleLogItem';
13+
const SINGLE_LOG_ITEM_VALUE = process.env.SINGLE_LOG_ITEM_VALUE || 'valueForSingleLogItem';
14+
const ARBITRARY_OBJECT_KEY = process.env.ARBITRARY_OBJECT_KEY || 'keyForArbitraryObject';
15+
const ARBITRARY_OBJECT_DATA = process.env.ARBITRARY_OBJECT_DATA || 'arbitrary object data';
1916

2017
const logger = new Logger({
2118
persistentLogAttributes: {
22-
[PERSISTENT_KEY]: PERSISTENT_VALUE,
23-
[REMOVABLE_KEY]: REMOVABLE_VALUE,
19+
[PERSISTENT_KEY]: PERSISTENT_VALUE, // This key-value pair will be added to every log
20+
[REMOVABLE_KEY]: REMOVABLE_VALUE, // This other one will be removed at runtime and not displayed in any log
2421
},
2522
});
2623

27-
const testFunction = async (event: LambdaEvent, context: Context): Promise<{requestId: string}> => {
28-
// Test feature 1: Log level filtering
29-
// Test feature 2: Context data
30-
// Test feature 3: Add and remove persistent additional log keys and value
31-
// Test feature 4: X-Ray Trace ID injection
32-
logger.removeKeys([REMOVABLE_KEY]);
33-
34-
const specialValue = event.invocation;
35-
if (specialValue === 0) {
36-
logger.appendKeys({
37-
[PERSISTENT_KEY_FIRST_INVOCATION_ONLY]: specialValue
38-
});
39-
}
40-
24+
const testFunction = async (event: TestEvent, context: Context): TestOutput => {
25+
// Test feature 1: Context data injection (all logs should have the same context data)
26+
// Test feature 2: Event log (this log should have the event data)
27+
// Test feature 3: Log level filtering (log level is set to INFO)
4128
logger.debug('##### This should not appear');
42-
logger.info('This is an INFO log with context and persistent key');
29+
30+
// Test feature 4: Add and remove persistent additional log keys and value
31+
logger.removeKeys([REMOVABLE_KEY]); // This key should not appear in any log (except the event log)
32+
logger.appendKeys({ // This key-value pair should appear in every log (except the event log)
33+
[RUNTIME_ADDED_KEY]: event.invocation,
34+
});
4335

4436
// Test feature 5: One-time additional log keys and values
4537
logger.info('This is an one-time log with an additional key-value', {
4638
[SINGLE_LOG_ITEM_KEY]: SINGLE_LOG_ITEM_VALUE,
4739
});
4840

49-
// Test feature 6: Logging an error object
41+
// Test feature 6: Error logging
5042
try {
5143
throw new Error(ERROR_MSG);
5244
} catch (e) {
5345
logger.error(ERROR_MSG, e as Error);
5446
}
5547

56-
// Test feature 7: Logging an arbitrary object
48+
// Test feature 7: Arbitrary object logging
5749
const obj: APIGatewayAuthorizerResult = {
5850
principalId: ARBITRARY_OBJECT_DATA,
5951
policyDocument: {
60-
Version: 'Version' + ARBITRARY_OBJECT_DATA,
52+
Version: 'Version 1',
6153
Statement: [{
62-
Effect: 'Effect' + ARBITRARY_OBJECT_DATA,
63-
Action: 'Action' + ARBITRARY_OBJECT_DATA,
64-
Resource: 'Resource' + ARBITRARY_OBJECT_DATA
54+
Effect: 'Allow',
55+
Action: 'geo:*',
56+
Resource: '*',
6557
}]
6658
}
6759
};
68-
6960
logger.info('A log entry with an object', { [ARBITRARY_OBJECT_KEY]: obj });
7061

62+
// Test feature 8: X-Ray Trace ID injection (all logs should have the same X-Ray Trace ID)
63+
7164
return {
7265
requestId: context.awsRequestId,
7366
};

0 commit comments

Comments
 (0)