From 2e2df564cefb504772b8aa18df516f24a2b87c9d Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 15 Apr 2025 11:21:09 +0100 Subject: [PATCH 1/4] fix(logger): Output a warning when the ALC log level is less verbose than log buffer --- packages/logger/src/Logger.ts | 8 +++++++ packages/logger/tests/unit/logBuffer.test.ts | 22 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 358f735f6..f17c1b9b0 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1378,6 +1378,14 @@ class Logger extends Utility implements LoggerInterface { this.#bufferConfig.bufferAtVerbosity = LogLevelThreshold[bufferAtLogLevel]; } + const AlcLogLevel = + this.getEnvVarsService().getAwsLogLevel() as keyof typeof LogLevelThreshold; + + if (LogLevelThreshold[AlcLogLevel] > this.#bufferConfig.bufferAtVerbosity) { + this.#warnOnce( + 'Advanced Loggging Controls (ALC) Log Level is higher than Log Buffering Log Level. Buffered logs will be filtered by ALC' + ); + } } /** diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 4f75b939c..0fe26118f 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -92,6 +92,28 @@ describe('Buffer logs', () => { ); }); + it('outputs a warning when the Advanced Logging Configuration Log Level is higher than the Log Buffering Log Level', () => { + // Assemble + process.env.AWS_LAMBDA_LOG_LEVEL = 'INFO'; + const logger = new Logger({ + logLevel: LogLevel.DEBUG, + logBufferOptions: { enabled: true, bufferAtVerbosity: 'DEBUG' }, + }); + + // Act + logger.debug('This is a debug'); + + // Assess + expect(console.warn).toHaveLogged( + expect.objectContaining({ + message: expect.stringContaining( + 'Advanced Loggging Controls (ALC) Log Level is higher than Log Buffering Log Level. Buffered logs will be filtered by ALC' + ), + level: LogLevel.WARN, + }) + ); + }); + it('outputs a warning when there is an error buffering the log', () => { // Prepare const logger = new Logger({ logBufferOptions: { maxBytes: 100 } }); From 5249f27b876353605af0566f62a19b2429a7f5c4 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 15 Apr 2025 16:14:24 +0100 Subject: [PATCH 2/4] Reword warning --- packages/logger/src/Logger.ts | 2 +- packages/logger/tests/unit/logBuffer.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index f17c1b9b0..4d0b50237 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1383,7 +1383,7 @@ class Logger extends Utility implements LoggerInterface { if (LogLevelThreshold[AlcLogLevel] > this.#bufferConfig.bufferAtVerbosity) { this.#warnOnce( - 'Advanced Loggging Controls (ALC) Log Level is higher than Log Buffering Log Level. Buffered logs will be filtered by ALC' + 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Buffered logs will be filtered by ALC' ); } } diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 0fe26118f..529d7debf 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -107,7 +107,7 @@ describe('Buffer logs', () => { expect(console.warn).toHaveLogged( expect.objectContaining({ message: expect.stringContaining( - 'Advanced Loggging Controls (ALC) Log Level is higher than Log Buffering Log Level. Buffered logs will be filtered by ALC' + 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Buffered logs will be filtered by ALC' ), level: LogLevel.WARN, }) From c2a0e9892f9ad783c254bc287717b2b577f6830d Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Wed, 16 Apr 2025 11:05:11 +0100 Subject: [PATCH 3/4] Warn when flushed messages will be lost due to ALC --- packages/logger/src/Logger.ts | 8 +++++++ packages/logger/tests/unit/logBuffer.test.ts | 25 +++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 4d0b50237..c8cc65e0a 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1451,6 +1451,14 @@ class Logger extends Utility implements LoggerInterface { ) ); } + const AlcLogLevel = + this.getEnvVarsService().getAwsLogLevel() as keyof typeof LogLevelThreshold; + + if (LogLevelThreshold[AlcLogLevel] > this.#bufferConfig.bufferAtVerbosity) { + this.#warnOnce( + 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Some logs might be missing.' + ); + } this.#buffer?.delete(traceId); } diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 529d7debf..ebe7d838c 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -92,7 +92,7 @@ describe('Buffer logs', () => { ); }); - it('outputs a warning when the Advanced Logging Configuration Log Level is higher than the Log Buffering Log Level', () => { + it('outputs a warning when the Advanced Logging Configuration Log Level is less verbose than the Log Buffering Log Level', () => { // Assemble process.env.AWS_LAMBDA_LOG_LEVEL = 'INFO'; const logger = new Logger({ @@ -114,6 +114,29 @@ describe('Buffer logs', () => { ); }); + it('When the buffer is flushed it outputs a warning if the Advanced Logging Configuration Log Level is less verbose than the Log Buffering Log Level', () => { + // Assemble + process.env.AWS_LAMBDA_LOG_LEVEL = 'INFO'; + const logger = new Logger({ + logLevel: LogLevel.DEBUG, + logBufferOptions: { enabled: true, bufferAtVerbosity: 'DEBUG' }, + }); + + // Act + logger.debug('This is a debug'); + logger.flushBuffer(); + + // Assess + expect(console.warn).toHaveLogged( + expect.objectContaining({ + message: expect.stringContaining( + 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Some logs might be missing.' + ), + level: LogLevel.WARN, + }) + ); + }); + it('outputs a warning when there is an error buffering the log', () => { // Prepare const logger = new Logger({ logBufferOptions: { maxBytes: 100 } }); From feea841a7a8420ba4cf4767c99aeeb45f747d1cf Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Wed, 16 Apr 2025 15:35:12 +0100 Subject: [PATCH 4/4] Store Advanced Logging Control level in Logger --- packages/logger/src/Logger.ts | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index c8cc65e0a..139839abc 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -133,6 +133,13 @@ class Logger extends Utility implements LoggerInterface { * Log level used internally by the current instance of Logger. */ private logLevel: number = LogLevelThreshold.INFO; + + /** + * Advanced Logging Control Log Level + * If not a valid value this will be left undefined, even if the + * environment variable AWS_LAMBDA_LOG_LEVEL is set + */ + #alcLogLevel?: Uppercase; /** * Persistent log attributes that will be logged in all log items. */ @@ -819,16 +826,15 @@ class Logger extends Utility implements LoggerInterface { } private awsLogLevelShortCircuit(selectedLogLevel?: string): boolean { - const awsLogLevel = this.getEnvVarsService().getAwsLogLevel(); - if (this.isValidLogLevel(awsLogLevel)) { - this.logLevel = LogLevelThreshold[awsLogLevel]; + if (this.#alcLogLevel !== undefined) { + this.logLevel = LogLevelThreshold[this.#alcLogLevel]; if ( this.isValidLogLevel(selectedLogLevel) && this.logLevel > LogLevelThreshold[selectedLogLevel] ) { this.#warnOnce( - `Current log level (${selectedLogLevel}) does not match AWS Lambda Advanced Logging Controls minimum log level (${awsLogLevel}). This can lead to data loss, consider adjusting them.` + `Current log level (${selectedLogLevel}) does not match AWS Lambda Advanced Logging Controls minimum log level (${this.#alcLogLevel}). This can lead to data loss, consider adjusting them.` ); } @@ -1306,6 +1312,11 @@ class Logger extends Utility implements LoggerInterface { ); // configurations that affect Logger behavior + const AlcLogLevel = this.getEnvVarsService().getAwsLogLevel(); + if (this.isValidLogLevel(AlcLogLevel)) { + this.#alcLogLevel = AlcLogLevel; + } + this.setLogEvent(); this.setInitialLogLevel(logLevel); this.setInitialSampleRate(sampleRateValue); @@ -1378,10 +1389,12 @@ class Logger extends Utility implements LoggerInterface { this.#bufferConfig.bufferAtVerbosity = LogLevelThreshold[bufferAtLogLevel]; } - const AlcLogLevel = - this.getEnvVarsService().getAwsLogLevel() as keyof typeof LogLevelThreshold; - if (LogLevelThreshold[AlcLogLevel] > this.#bufferConfig.bufferAtVerbosity) { + if ( + this.#alcLogLevel !== undefined && + LogLevelThreshold[this.#alcLogLevel] > + this.#bufferConfig.bufferAtVerbosity + ) { this.#warnOnce( 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Buffered logs will be filtered by ALC' ); @@ -1451,10 +1464,12 @@ class Logger extends Utility implements LoggerInterface { ) ); } - const AlcLogLevel = - this.getEnvVarsService().getAwsLogLevel() as keyof typeof LogLevelThreshold; - if (LogLevelThreshold[AlcLogLevel] > this.#bufferConfig.bufferAtVerbosity) { + if ( + this.#alcLogLevel !== undefined && + LogLevelThreshold[this.#alcLogLevel] > + this.#bufferConfig.bufferAtVerbosity + ) { this.#warnOnce( 'Advanced Loggging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. Some logs might be missing.' );