diff --git a/docs/core/logger.md b/docs/core/logger.md index a1a0d05f97..7cac4defb6 100644 --- a/docs/core/logger.md +++ b/docs/core/logger.md @@ -388,6 +388,40 @@ The error will be logged with default key name `error`, but you can also pass yo ## Advanced +### Log levels + +The default log level is `INFO` and can be set using the `logLevel` constructor option or by using the `LOG_LEVEL` environment variable. + +Logger supports the following log levels: + +| Level | Numeric value | +| ---------- | ------------- | +| `DEBUG` | 8 | +| `INFO` | 12 | +| `WARN` | 16 | +| `ERROR` | 20 | +| `CRITICAL` | 24 | +| `SILENT` | 28 | + +You can access the current log level by using the `getLevelName()` method. This method returns the name of the current log level as a string. If you want to change the log level at runtime, you can use the `setLogLevel()` method. This method accepts a string value that represents the log level you want to set, both lower and upper case values are supported. + +```typescript +--8<-- "docs/snippets/logger/logLevel.ts" +``` + +If you want to access the numeric value of the current log level, you can use the `level` property. For example, if the current log level is `INFO`, `logger.level` property will return `12`. + +#### Silencing logs + +The `SILENT` log level provides a simple and efficient way to suppress all log messages without the need to modify your code. When you set this log level, all log messages, regardless of their severity, will be silenced. + +This feature is useful when you want to have your code instrumented to produce logs, but due to some requirement or business decision, you prefer to not emit them. + +By setting the log level to `SILENT`, which can be done either through the `logLevel` constructor option or by using the `LOG_LEVEL` environment variable, you can easily suppress all logs as needed. + +!!! note + Use the `SILENT` log level with care, as it can make it more challenging to monitor and debug your application. Therefore, we advise using this log level judiciously. + ### Using multiple Logger instances across your code The `createChild` method allows you to create a child instance of the Logger, which inherits all of the attributes from its parent. You have the option to override any of the settings and attributes from the parent logger, including [its settings](#utility-settings), any [persistent attributes](#appending-persistent-additional-log-keys-and-values), and [the log formatter](#custom-log-formatter-bring-your-own-formatter). Once a child logger is created, the logger and its parent will act as separate instances of the Logger class, and as such any change to one won't be applied to the other. @@ -556,17 +590,6 @@ For example, by setting the "sample rate" to `0.5`, roughly 50% of your lambda i } ``` -### Silencing logs - -The `SILENT` log level provides a simple and efficient way to suppress all log messages without the need to modify your code. When you set this log level, all log messages, regardless of their severity, will be silenced. - -This feature is useful when you want to have your code instrumented to produce logs, but due to some requirement or business decision, you prefer to not emit them. - -By setting the log level to `SILENT`, which can be done either through the `logLevel` constructor option or by using the `LOG_LEVEL` environment variable, you can easily suppress all logs as needed. - -!!! note - Use the `SILENT` log level with care, as it can make it more challenging to monitor and debug your application. Therefore, we advise using this log level judiciously. - ### Custom Log formatter (Bring Your Own Formatter) You can customize the structure (keys and values) of your log items by passing a custom log formatter, an object that implements the `LogFormatter` abstract class. diff --git a/docs/snippets/logger/logLevel.ts b/docs/snippets/logger/logLevel.ts new file mode 100644 index 0000000000..5a7ceacb65 --- /dev/null +++ b/docs/snippets/logger/logLevel.ts @@ -0,0 +1,7 @@ +import { Logger } from '@aws-lambda-powertools/logger'; + +const logger = new Logger(); + +logger.getLevelName(); // returns "INFO" +logger.setLogLevel('DEBUG'); +logger.level; // returns 8 diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index e9f2fd7be6..bb20e957e9 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1,4 +1,5 @@ -import { Console } from 'console'; +import { randomInt } from 'node:crypto'; +import { Console } from 'node:console'; import type { Context, Handler } from 'aws-lambda'; import { Utility } from '@aws-lambda-powertools/commons'; import { LogFormatterInterface, PowertoolLogFormatter } from './formatter'; @@ -111,13 +112,21 @@ import type { * @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/core/logger/ */ class Logger extends Utility implements ClassThatLogs { - // console is initialized in the constructor in setOptions() + /** + * Console instance used to print logs. + * + * In AWS Lambda, we create a new instance of the Console class so that we can have + * full control over the output of the logs. In testing environments, we use the + * default console instance. + * + * This property is initialized in the constructor in setOptions(). + * + * @private + */ private console!: Console; private customConfigService?: ConfigServiceInterface; - private static readonly defaultLogLevel: Uppercase = 'INFO'; - // envVarsService is always initialized in the constructor in setOptions() private envVarsService!: EnvironmentVariablesService; @@ -127,9 +136,16 @@ class Logger extends Utility implements ClassThatLogs { private logIndentation: number = LogJsonIndent.COMPACT; - private logLevel?: Uppercase; + /** + * Log level used internally by the current instance of Logger. + */ + private logLevel = 12; - // Log levels are in ascending order from the most verbose to the least verbose (no logs) + /** + * Log level thresholds used internally by the current instance of Logger. + * + * The levels are in ascending order from the most verbose to the least verbose (no logs). + */ private readonly logLevelThresholds: LogLevelThresholds = { DEBUG: 8, INFO: 12, @@ -145,6 +161,16 @@ class Logger extends Utility implements ClassThatLogs { private powertoolLogData: PowertoolLogData = {}; + /** + * Log level used by the current instance of Logger. + * + * Returns the log level as a number. The higher the number, the less verbose the logs. + * To get the log level name, use the {@link getLevelName()} method. + */ + public get level(): number { + return this.logLevel; + } + /** * It initializes the Logger class with an optional set of options (settings). * * @@ -206,7 +232,7 @@ class Logger extends Utility implements ClassThatLogs { */ public createChild(options: ConstructorOptions = {}): Logger { const parentsOptions = { - logLevel: this.getLogLevel(), + logLevel: this.getLevelName(), customConfigService: this.getCustomConfigService(), logFormatter: this.getLogFormatter(), }; @@ -235,7 +261,7 @@ class Logger extends Utility implements ClassThatLogs { input: LogItemMessage, ...extraInput: LogItemExtraInput ): void { - this.processLogItem('CRITICAL', input, extraInput); + this.processLogItem(24, input, extraInput); } /** @@ -246,7 +272,7 @@ class Logger extends Utility implements ClassThatLogs { * @returns {void} */ public debug(input: LogItemMessage, ...extraInput: LogItemExtraInput): void { - this.processLogItem('DEBUG', input, extraInput); + this.processLogItem(8, input, extraInput); } /** @@ -257,7 +283,19 @@ class Logger extends Utility implements ClassThatLogs { * @returns {void} */ public error(input: LogItemMessage, ...extraInput: LogItemExtraInput): void { - this.processLogItem('ERROR', input, extraInput); + this.processLogItem(20, input, extraInput); + } + + /** + * Get the log level name of the current instance of Logger. + * + * It returns the log level name, i.e. `INFO`, `DEBUG`, etc. + * To get the log level as a number, use the {@link Logger.level} property. + * + * @returns {Uppercase} The log level name. + */ + public getLevelName(): Uppercase { + return this.getLogLevelNameFromNumber(this.logLevel); } /** @@ -298,7 +336,7 @@ class Logger extends Utility implements ClassThatLogs { * @returns {void} */ public info(input: LogItemMessage, ...extraInput: LogItemExtraInput): void { - this.processLogItem('INFO', input, extraInput); + this.processLogItem(12, input, extraInput); } /** @@ -453,6 +491,19 @@ class Logger extends Utility implements ClassThatLogs { }); } + /** + * Set the log level for this Logger instance. + * + * @param logLevel The log level to set, i.e. `error`, `warn`, `info`, `debug`, etc. + */ + public setLogLevel(logLevel: LogLevel): void { + if (this.isValidLogLevel(logLevel)) { + this.logLevel = this.logLevelThresholds[logLevel]; + } else { + throw new Error(`Invalid log level: ${logLevel}`); + } + } + /** * It sets the given attributes (key-value pairs) to all log items generated by this Logger instance. * Note: this replaces the pre-existing value. @@ -500,7 +551,28 @@ class Logger extends Utility implements ClassThatLogs { * @returns {void} */ public warn(input: LogItemMessage, ...extraInput: LogItemExtraInput): void { - this.processLogItem('WARN', input, extraInput); + this.processLogItem(16, input, extraInput); + } + + /** + * Decides whether the current log item should be printed or not. + * + * The decision is based on the log level and the sample rate value. + * A log item will be printed if: + * 1. The log level is greater than or equal to the Logger's log level. + * 2. The log level is less than the Logger's log level, but the + * current sampling value is set to `true`. + * + * @param {number} logLevel + * @returns {boolean} + * @protected + */ + protected shouldPrint(logLevel: number): boolean { + if (logLevel >= this.logLevel) { + return true; + } + + return this.getLogsSampled(); } /** @@ -524,20 +596,20 @@ class Logger extends Utility implements ClassThatLogs { * - Formats all the log attributes; * * @private - * @param {LogLevel} logLevel + * @param {number} logLevel * @param {LogItemMessage} input * @param {LogItemExtraInput} extraInput * @returns {LogItem} */ private createAndPopulateLogItem( - logLevel: LogLevel, + logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput ): LogItem { // TODO: this method's logic is hard to understand, there is an opportunity here to simplify this logic. const unformattedBaseAttributes = merge( { - logLevel, + logLevel: this.getLogLevelNameFromNumber(logLevel), timestamp: new Date(), message: typeof input === 'string' ? input : input.message, xRayTraceId: this.envVarsService.getXrayTraceId(), @@ -602,17 +674,23 @@ class Logger extends Utility implements ClassThatLogs { } /** - * It returns the log level set for the Logger instance. + * Get the log level name from the log level number. * - * Even though logLevel starts as undefined, it will always be set to a value - * during the Logger instance's initialization. So, we can safely use the non-null - * assertion operator here. + * For example, if the log level is 16, it will return 'WARN'. * - * @private - * @returns {LogLevel} + * @param logLevel - The log level to get the name of + * @returns - The name of the log level */ - private getLogLevel(): Uppercase { - return this.logLevel!; + private getLogLevelNameFromNumber(logLevel: number): Uppercase { + const found = Object.entries(this.logLevelThresholds).find( + ([key, value]) => { + if (value === logLevel) { + return key; + } + } + )!; + + return found[0] as Uppercase; } /** @@ -690,17 +768,20 @@ class Logger extends Utility implements ClassThatLogs { /** * It prints a given log with given log level. * - * @param {LogLevel} logLevel + * @param {number} logLevel * @param {LogItem} log * @private */ - private printLog(logLevel: LogLevel, log: LogItem): void { + private printLog(logLevel: number, log: LogItem): void { log.prepareForPrint(); const consoleMethod = - logLevel === 'CRITICAL' + logLevel === 24 ? 'error' - : (logLevel.toLowerCase() as keyof Omit); + : (this.getLogLevelNameFromNumber(logLevel).toLowerCase() as keyof Omit< + ClassThatLogs, + 'critical' + >); this.console[consoleMethod]( JSON.stringify( @@ -714,13 +795,13 @@ class Logger extends Utility implements ClassThatLogs { /** * It prints a given log with given log level. * - * @param {Uppercase} logLevel + * @param {number} logLevel * @param {LogItemMessage} input * @param {LogItemExtraInput} extraInput * @private */ private processLogItem( - logLevel: Uppercase, + logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput ): void { @@ -778,6 +859,40 @@ class Logger extends Utility implements ClassThatLogs { this.envVarsService = new EnvironmentVariablesService(); } + /** + * Sets the initial Logger log level based on the following order: + * 1. If a log level is passed to the constructor, it sets it. + * 2. If a log level is set via custom config service, it sets it. + * 3. If a log level is set via env variables, it sets it. + * + * If none of the above is true, the default log level applies (INFO). + * + * @private + * @param {LogLevel} [logLevel] - Log level passed to the constructor + */ + private setInitialLogLevel(logLevel?: LogLevel): void { + const constructorLogLevel = logLevel?.toUpperCase(); + if (this.isValidLogLevel(constructorLogLevel)) { + this.logLevel = this.logLevelThresholds[constructorLogLevel]; + + return; + } + const customConfigValue = this.getCustomConfigService() + ?.getLogLevel() + ?.toUpperCase(); + if (this.isValidLogLevel(customConfigValue)) { + this.logLevel = this.logLevelThresholds[customConfigValue]; + + return; + } + const envVarsValue = this.getEnvVarsService()?.getLogLevel()?.toUpperCase(); + if (this.isValidLogLevel(envVarsValue)) { + this.logLevel = this.logLevelThresholds[envVarsValue]; + + return; + } + } + /** * If the log event feature is enabled via env variable, it sets a property that tracks whether * the event passed to the Lambda function handler should be logged or not. @@ -816,38 +931,6 @@ class Logger extends Utility implements ClassThatLogs { } } - /** - * It sets the Logger's instance log level. - * - * @private - * @param {LogLevel} logLevel - * @returns {void} - */ - private setLogLevel(logLevel?: LogLevel): void { - const constructorLogLevel = logLevel?.toUpperCase(); - if (this.isValidLogLevel(constructorLogLevel)) { - this.logLevel = constructorLogLevel; - - return; - } - const customConfigValue = this.getCustomConfigService() - ?.getLogLevel() - ?.toUpperCase(); - if (this.isValidLogLevel(customConfigValue)) { - this.logLevel = customConfigValue; - - return; - } - const envVarsValue = this.getEnvVarsService()?.getLogLevel()?.toUpperCase(); - if (this.isValidLogLevel(envVarsValue)) { - this.logLevel = envVarsValue; - - return; - } - - this.logLevel = Logger.defaultLogLevel; - } - /** * If the sample rate feature is enabled, it sets a property that tracks whether this Lambda function invocation * will print logs or not. @@ -857,10 +940,9 @@ class Logger extends Utility implements ClassThatLogs { */ private setLogsSampled(): void { const sampleRateValue = this.getSampleRateValue(); - // TODO: revisit Math.random() as it's not a real randomization this.logsSampled = sampleRateValue !== undefined && - (sampleRateValue === 1 || Math.random() < sampleRateValue); + (sampleRateValue === 1 || randomInt(0, 100) / 100 <= sampleRateValue); } /** @@ -886,7 +968,7 @@ class Logger extends Utility implements ClassThatLogs { // order is important, it uses EnvVarsService() this.setConsole(); this.setCustomConfigService(customConfigService); - this.setLogLevel(logLevel); + this.setInitialLogLevel(logLevel); this.setSampleRateValue(sampleRateValue); this.setLogsSampled(); this.setLogFormatter(logFormatter); @@ -930,24 +1012,6 @@ class Logger extends Utility implements ClassThatLogs { persistentLogAttributes ); } - - /** - * It checks whether the current log item should/can be printed. - * - * @param {Uppercase} logLevel - * @private - * @returns {boolean} - */ - private shouldPrint(logLevel: Uppercase): boolean { - if ( - this.logLevelThresholds[logLevel] >= - this.logLevelThresholds[this.getLogLevel()] - ) { - return true; - } - - return this.getLogsSampled(); - } } export { Logger }; diff --git a/packages/logger/src/helpers.ts b/packages/logger/src/helpers.ts index e143f83834..dc1e94d45a 100644 --- a/packages/logger/src/helpers.ts +++ b/packages/logger/src/helpers.ts @@ -1,6 +1,11 @@ import { Logger } from '.'; import { ConstructorOptions } from './types'; +/** + * Create a new logger instance with the given options. + * + * @deprecated - This function will be removed in the next major release. Use the Logger class directly instead. + */ const createLogger = (options: ConstructorOptions = {}): Logger => new Logger(options); diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index 11bc29e7a0..61424c04c1 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -16,6 +16,7 @@ import { LogJsonIndent, ConstructorOptions, LogLevelThresholds, + LogLevel, } from '../../src/types'; import { Context } from 'aws-lambda'; import { Console } from 'console'; @@ -798,7 +799,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: 0, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1621,7 +1622,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1644,7 +1645,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1667,7 +1668,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1733,7 +1734,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1756,7 +1757,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1782,7 +1783,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1805,7 +1806,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'ERROR', + logLevel: 20, logLevelThresholds: { ...logLevelThresholds, }, @@ -1849,7 +1850,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1872,7 +1873,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1902,7 +1903,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: INDENTATION, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -1943,7 +1944,7 @@ describe('Class: Logger', () => { logEvent: false, logIndentation: 0, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'DEBUG', + logLevel: 8, logLevelThresholds: { ...logLevelThresholds, }, @@ -2174,4 +2175,28 @@ describe('Class: Logger', () => { }); }); }); + + describe('Method: setLogLevel', () => { + test('it sets the correct log level provided', () => { + // Prepare + const logger = new Logger(); + + // Act + logger.setLogLevel('ERROR'); + + // Assess + expect(logger.level).toBe(20); + expect(logger.getLevelName()).toBe('ERROR'); + }); + + test('it throws when passed an invalid log level name', () => { + // Prepare + const logger = new Logger(); + + // Act & Assess + expect(() => logger.setLogLevel('INVALID' as LogLevel)).toThrow( + 'Invalid log level: INVALID' + ); + }); + }); }); diff --git a/packages/logger/tests/unit/helpers.test.ts b/packages/logger/tests/unit/helpers.test.ts index 4f2c6ee743..ba16e38c31 100644 --- a/packages/logger/tests/unit/helpers.test.ts +++ b/packages/logger/tests/unit/helpers.test.ts @@ -55,7 +55,7 @@ describe('Helper: createLogger function', () => { envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, defaultServiceName: 'service_undefined', - logLevel: 'DEBUG', + logLevel: 8, logFormatter: expect.any(PowertoolLogFormatter), }) ); @@ -88,7 +88,7 @@ describe('Helper: createLogger function', () => { logEvent: false, logIndentation: 0, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'WARN', + logLevel: 16, console: expect.any(Console), logLevelThresholds: { ...logLevelThresholds, @@ -125,7 +125,7 @@ describe('Helper: createLogger function', () => { logEvent: false, logIndentation: 0, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'INFO', + logLevel: 12, console: expect.any(Console), logLevelThresholds: { ...logLevelThresholds, @@ -164,7 +164,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: expect.any(LogFormatter), }) ); @@ -193,7 +193,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: {}, }) ); @@ -222,7 +222,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'ERROR', + logLevel: 20, logFormatter: expect.any(PowertoolLogFormatter), }) ); @@ -251,7 +251,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'WARN', + logLevel: 16, logFormatter: expect.any(PowertoolLogFormatter), }) ); @@ -275,7 +275,7 @@ describe('Helper: createLogger function', () => { logEvent: false, logIndentation: 0, logFormatter: expect.any(PowertoolLogFormatter), - logLevel: 'INFO', + logLevel: 12, console: expect.any(Console), logLevelThresholds: { ...logLevelThresholds, @@ -314,7 +314,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: {}, }) ); @@ -369,7 +369,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: configService, - logLevel: 'INFO', + logLevel: 12, logFormatter: {}, }) ); @@ -412,7 +412,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: {}, }) ); @@ -441,7 +441,7 @@ describe('Helper: createLogger function', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: {}, }) ); diff --git a/packages/logger/tests/unit/middleware/middy.test.ts b/packages/logger/tests/unit/middleware/middy.test.ts index 2a40a211c6..4c97a93444 100644 --- a/packages/logger/tests/unit/middleware/middy.test.ts +++ b/packages/logger/tests/unit/middleware/middy.test.ts @@ -73,7 +73,7 @@ describe('Middy middleware', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: expect.any(PowertoolLogFormatter), }) ); @@ -112,7 +112,7 @@ describe('Middy middleware', () => { }, envVarsService: expect.any(EnvironmentVariablesService), customConfigService: undefined, - logLevel: 'DEBUG', + logLevel: 8, logFormatter: expect.any(PowertoolLogFormatter), console: expect.any(Console), });