From 67e615f664bc337986cca18d84a81937aa72c178 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Fri, 21 Feb 2025 12:46:30 +0000 Subject: [PATCH 1/8] feat(logger): Enable log buffering feature This commit enables the buffering feature for the logger utility It allows the user to configure the buffering functionality in the logger constructor. --- packages/logger/src/Logger.ts | 57 +++- packages/logger/src/types/Logger.ts | 35 ++- packages/logger/tests/unit/logBuffer.test.ts | 267 +++++++++++-------- 3 files changed, 239 insertions(+), 120 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 2f342f6ff7..62ac16bf64 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -172,25 +172,28 @@ class Logger extends Utility implements LoggerInterface { /** * Represents whether the buffering functionality is enabled in the logger */ - protected isBufferEnabled = false; + protected isBufferEnabled = true; + /** + * Whether the buffer should be flushed when an error is logged + */ + protected flushOnErrorLog = true; /** * Log level threshold for the buffer * Logs with a level lower than this threshold will be buffered + * Default is DEBUG */ - protected bufferLogThreshold: number = LogLevelThreshold.DEBUG; + protected bufferAtVerbosity: number = LogLevelThreshold.DEBUG; /** * Max size of the buffer. Additions to the buffer beyond this size will * cause older logs to be evicted from the buffer */ - readonly #maxBufferBytesSize = 1024; + #maxBufferBytesSize = 1024; /** * Contains buffered logs, grouped by _X_AMZN_TRACE_ID, each group with a max size of `maxBufferBytesSize` */ - readonly #buffer: CircularMap = new CircularMap({ - maxBytesSize: this.#maxBufferBytesSize, - }); + #buffer?: CircularMap; /** * Log level used by the current instance of Logger. @@ -330,6 +333,9 @@ class Logger extends Utility implements LoggerInterface { * @param extraInput - The extra input to log. */ public error(input: LogItemMessage, ...extraInput: LogItemExtraInput): void { + if (this.isBufferEnabled && this.flushOnErrorLog) { + this.flushBuffer(); + } this.processLogItem(LogLevelThreshold.ERROR, input, extraInput); } @@ -1167,6 +1173,7 @@ class Logger extends Utility implements LoggerInterface { environment, jsonReplacerFn, logRecordOrder, + logBufferOptions, } = options; if (persistentLogAttributes && persistentKeys) { @@ -1193,6 +1200,10 @@ class Logger extends Utility implements LoggerInterface { this.setLogIndentation(); this.#jsonReplacerFn = jsonReplacerFn; + if (logBufferOptions !== undefined) { + this.#setLogBuffering(logBufferOptions); + } + return this; } @@ -1223,6 +1234,30 @@ class Logger extends Utility implements LoggerInterface { persistentKeys && this.appendPersistentKeys(persistentKeys); } + #setLogBuffering( + options: NonNullable + ) { + if (options.maxBytes !== undefined) { + this.#maxBufferBytesSize = options.maxBytes; + } + + this.#buffer = new CircularMap({ + maxBytesSize: this.#maxBufferBytesSize, + }); + + if (options.enabled !== undefined) { + this.isBufferEnabled = options.enabled; + } + + const bufferAtLogLevel = options.bufferAtVerbosity?.toUpperCase(); + + if (this.isValidLogLevel(bufferAtLogLevel)) { + this.bufferAtVerbosity = LogLevelThreshold[bufferAtLogLevel]; + + return; + } + } + /** * Add a log to the buffer * @param xrayTraceId - _X_AMZN_TRACE_ID of the request @@ -1242,20 +1277,20 @@ class Logger extends Utility implements LoggerInterface { this.logIndentation ); - this.#buffer.setItem(xrayTraceId, stringified, logLevel); + this.#buffer?.setItem(xrayTraceId, stringified, logLevel); } /** * Flushes all items of the respective _X_AMZN_TRACE_ID within * the buffer. */ - protected flushBuffer(): void { + flushBuffer(): void { const traceId = this.envVarsService.getXrayTraceId(); if (traceId === undefined) { return; } - const buffer = this.#buffer.get(traceId); + const buffer = this.#buffer?.get(traceId); if (buffer === undefined) { return; } @@ -1280,7 +1315,7 @@ class Logger extends Utility implements LoggerInterface { ); } - this.#buffer.delete(traceId); + this.#buffer?.delete(traceId); } /** * Tests if the log meets the criteria to be buffered @@ -1294,7 +1329,7 @@ class Logger extends Utility implements LoggerInterface { return ( this.isBufferEnabled && traceId !== undefined && - logLevel <= this.bufferLogThreshold + logLevel <= this.bufferAtVerbosity ); } } diff --git a/packages/logger/src/types/Logger.ts b/packages/logger/src/types/Logger.ts index 1e453f1ee5..f15503248c 100644 --- a/packages/logger/src/types/Logger.ts +++ b/packages/logger/src/types/Logger.ts @@ -173,12 +173,44 @@ type LogRecordOrderOption = { logFormatter?: never; }; +/** + * Options for the `logBuffer` constructor option. + * + * Used to configure the log buffer functionality. + */ +type LogBufferOption = { + logBufferOptions?: { + /** + * Whether logs should be buffered + */ + enabled?: boolean; + + /** + * Maximum size in bytes of each buffer. + */ + maxBytes?: number; + /** + * Flush the buffer when an error is logged + */ + flushOnErrorLog?: boolean; + /** + * The threshold to buffer logs. Logs with a level below + * this threshold will be buffered + */ + bufferAtVerbosity?: Omit< + LogLevel, + 'ERROR' | 'error' | 'CRITICAL' | 'critical' | 'SILENT' | 'silent' + >; + }; +}; + /** * Options to configure the Logger. */ type ConstructorOptions = BaseConstructorOptions & (PersistentKeysOption | DeprecatedPersistentKeysOption) & - (LogFormatterOption | LogRecordOrderOption); + (LogFormatterOption | LogRecordOrderOption) & + LogBufferOption; type LogItemMessage = string | LogAttributesWithMessage; type LogItemExtraInput = [Error | string] | LogAttributes[]; @@ -194,6 +226,7 @@ type LoggerInterface = { critical(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; debug(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; error(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; + flushBuffer(): void; getLevelName(): Uppercase; getLogEvent(): boolean; getPersistentLogAttributes(): LogAttributes; diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 9ba2923bc3..026449c588 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -1,140 +1,191 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Logger } from '../../src/Logger.js'; -import { LogLevelThreshold } from '../../src/constants.js'; +import { LogLevel } from '../../src/constants.js'; class TestLogger extends Logger { - public enableBuffering() { - this.isBufferEnabled = true; - } - public disableBuffering() { - this.isBufferEnabled = false; - } - - public flushBufferWrapper(): void { - this.flushBuffer(); - } - public overrideBufferLogItem(): void { this.bufferLogItem = vi.fn().mockImplementation(() => { throw new Error('bufferLogItem error'); }); } - - public setbufferLevelThreshold(level: number): void { - this.bufferLogThreshold = level; - } } +describe('Log Buffer', () => { + describe('Configuration', () => { + const ENVIRONMENT_VARIABLES = process.env; + + beforeEach(() => { + process.env = { + ...ENVIRONMENT_VARIABLES, + POWERTOOLS_LOGGER_LOG_EVENT: 'true', + POWERTOOLS_DEV: 'true', + }; + vi.clearAllMocks(); + }); -describe('bufferLog', () => { - it('outputs a warning when there is an error buffering the log', () => { - // Prepare - process.env.POWERTOOLS_DEV = 'true'; - const logger = new TestLogger(); - logger.enableBuffering(); - logger.overrideBufferLogItem(); - - // Act - logger.debug('This is a debug'); + it('does not buffer logs when disabled', () => { + // Prepare + const logger = new TestLogger({ + logLevel: LogLevel.ERROR, + logBufferOptions: { enabled: false }, + }); + + // Act + logger.debug('This is a log message'); + logger.flushBuffer(); + // Assess + expect(console.debug).toBeCalledTimes(0); + }); - // Assess - expect(console.debug).toBeCalledTimes(1); - expect(console.warn).toBeCalledTimes(1); + it('sets a max buffer sized when specified', () => { + // Prepare + const logger = new TestLogger({ + logBufferOptions: { maxBytes: 250, bufferAtVerbosity: LogLevel.DEBUG }, + }); + + // Act + logger.debug('this is a debug'); + logger.debug('this is a debug'); + logger.flushBuffer(); + + // Assess + expect(console.debug).toBeCalledTimes(1); + expect(console.warn).toHaveLogged( + expect.objectContaining({ + level: 'WARN', + message: + 'Some logs are not displayed because they were evicted from the buffer. Increase buffer size to store more logs in the buffer', + }) + ); + }); }); -}); -describe('flushBuffer', () => { - const ENVIRONMENT_VARIABLES = process.env; + describe('Functionality', () => { + const ENVIRONMENT_VARIABLES = process.env; - beforeEach(() => { - process.env = { - ...ENVIRONMENT_VARIABLES, - POWERTOOLS_LOGGER_LOG_EVENT: 'true', - POWERTOOLS_DEV: 'true', - }; - vi.clearAllMocks(); - }); + beforeEach(() => { + process.env = { + ...ENVIRONMENT_VARIABLES, + POWERTOOLS_LOGGER_LOG_EVENT: 'true', + POWERTOOLS_DEV: 'true', + }; + vi.clearAllMocks(); + }); + it('outputs a warning when there is an error buffering the log', () => { + // Prepare + process.env.POWERTOOLS_DEV = 'true'; + const logger = new TestLogger(); + logger.overrideBufferLogItem(); + + // Act + logger.debug('This is a debug'); + + // Assess + expect(console.debug).toBeCalledTimes(1); + expect(console.warn).toBeCalledTimes(1); + }); - it('outputs buffered logs', () => { - // Prepare - const logger = new TestLogger({ logLevel: 'SILENT' }); - logger.enableBuffering(); - logger.setbufferLevelThreshold(LogLevelThreshold.CRITICAL); + it('outputs buffered logs', () => { + // Prepare + const logger = new TestLogger({ + logLevel: 'SILENT', + logBufferOptions: { bufferAtVerbosity: LogLevel.CRITICAL }, + }); - // Act - logger.debug('This is a debug'); - logger.warn('This is a warning'); - logger.critical('this is a critical'); + // Act + logger.debug('This is a debug'); + logger.warn('This is a warning'); + logger.critical('this is a critical'); - // Assess - expect(console.warn).toHaveBeenCalledTimes(0); - expect(console.error).toHaveBeenCalledTimes(0); + // Assess + expect(console.warn).toHaveBeenCalledTimes(0); + expect(console.error).toHaveBeenCalledTimes(0); - // Act - logger.flushBufferWrapper(); + // Act + logger.flushBuffer(); - // Assess - expect(console.warn).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledTimes(1); - }); + // Assess + expect(console.warn).toHaveBeenCalledTimes(1); + expect(console.error).toHaveBeenCalledTimes(1); + }); - it('handles an empty buffer', () => { - // Prepare - const logger = new TestLogger(); - logger.enableBuffering(); + it('handles an empty buffer', () => { + // Prepare + const logger = new TestLogger(); - // Act - logger.flushBufferWrapper(); - }); + // Act + logger.flushBuffer(); + }); - it('does not output buffered logs when trace id is not set', () => { - // Prepare - process.env._X_AMZN_TRACE_ID = undefined; - const logger = new TestLogger({}); - logger.enableBuffering(); + it('does not output buffered logs when trace id is not set', () => { + // Prepare + process.env._X_AMZN_TRACE_ID = undefined; + const logger = new TestLogger({}); - // Act - logger.debug('This is a debug'); - logger.warn('this is a warning'); + // Act + logger.debug('This is a debug'); + logger.warn('this is a warning'); - // Assess - expect(console.debug).toHaveBeenCalledTimes(0); - expect(console.warn).toHaveBeenCalledTimes(1); + // Assess + expect(console.debug).toHaveBeenCalledTimes(0); + expect(console.warn).toHaveBeenCalledTimes(1); - // Act - logger.flushBufferWrapper(); + // Act + logger.flushBuffer(); - // Assess - expect(console.debug).toHaveBeenCalledTimes(0); - expect(console.warn).toHaveBeenCalledTimes(1); - }); + // Assess + expect(console.debug).toHaveBeenCalledTimes(0); + expect(console.warn).toHaveBeenCalledTimes(1); + }); - it('outputs a warning when buffered logs have been evicted', () => { - // Prepare - const logger = new TestLogger({ logLevel: 'ERROR' }); - logger.enableBuffering(); - logger.setbufferLevelThreshold(LogLevelThreshold.INFO); + it('outputs a warning when buffered logs have been evicted', () => { + // Prepare + const logger = new TestLogger({ + logLevel: LogLevel.ERROR, + logBufferOptions: { bufferAtVerbosity: LogLevel.INFO }, + }); + + // Act + const longMessage = 'blah'.repeat(10); + + let i = 0; + while (i < 4) { + logger.info( + `${i} This is a really long log message intended to exceed the buffer ${longMessage}` + ); + i++; + } + + // Act + logger.flushBuffer(); + + // Assess + expect(console.warn).toHaveLogged( + expect.objectContaining({ + level: LogLevel.WARN, + message: + 'Some logs are not displayed because they were evicted from the buffer. Increase buffer size to store more logs in the buffer', + }) + ); + }); - // Act - const longMessage = 'blah'.repeat(10); + it('it flushes the buffer when an error in logged', () => { + // Prepare + const logger = new TestLogger({ + logLevel: LogLevel.ERROR, + logBufferOptions: { bufferAtVerbosity: LogLevel.DEBUG }, + }); - let i = 0; - while (i < 4) { - logger.info( - `${i} This is a really long log message intended to exceed the buffer ${longMessage}` - ); - i++; - } - - // Act - logger.flushBufferWrapper(); - - // Assess - expect(console.warn).toHaveLogged( - expect.objectContaining({ - level: 'WARN', - message: - 'Some logs are not displayed because they were evicted from the buffer. Increase buffer size to store more logs in the buffer', - }) - ); + const spy = vi.spyOn(logger, 'flushBuffer'); + + // Act + logger.debug('This is a log message'); + + logger.error('This is an error message'); + + // Assess + expect(spy).toBeCalledTimes(1); + expect(console.debug).toBeCalledTimes(1); + expect(console.error).toBeCalledTimes(1); + }); }); }); From a342171eb75d98289d06db90a8c25d54825bafba Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:06:28 +0000 Subject: [PATCH 2/8] Disable buffering by default --- packages/logger/src/Logger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 62ac16bf64..a1cd8af79e 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -172,7 +172,7 @@ class Logger extends Utility implements LoggerInterface { /** * Represents whether the buffering functionality is enabled in the logger */ - protected isBufferEnabled = true; + protected isBufferEnabled = false; /** * Whether the buffer should be flushed when an error is logged From 7f04bd4f8a897fcb1efa21dbaa06e9b9bdd42256 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:06:46 +0000 Subject: [PATCH 3/8] Change default buffer size --- packages/logger/src/Logger.ts | 4 ++-- packages/logger/src/types/Logger.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index a1cd8af79e..be16b00a5b 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -188,7 +188,7 @@ class Logger extends Utility implements LoggerInterface { * Max size of the buffer. Additions to the buffer beyond this size will * cause older logs to be evicted from the buffer */ - #maxBufferBytesSize = 1024; + #maxBufferBytesSize = 20480; /** * Contains buffered logs, grouped by _X_AMZN_TRACE_ID, each group with a max size of `maxBufferBytesSize` @@ -1284,7 +1284,7 @@ class Logger extends Utility implements LoggerInterface { * Flushes all items of the respective _X_AMZN_TRACE_ID within * the buffer. */ - flushBuffer(): void { + public flushBuffer(): void { const traceId = this.envVarsService.getXrayTraceId(); if (traceId === undefined) { return; diff --git a/packages/logger/src/types/Logger.ts b/packages/logger/src/types/Logger.ts index f15503248c..f326f2e538 100644 --- a/packages/logger/src/types/Logger.ts +++ b/packages/logger/src/types/Logger.ts @@ -186,7 +186,8 @@ type LogBufferOption = { enabled?: boolean; /** - * Maximum size in bytes of each buffer. + * Maximum size of the buffer in bytes + * @default `20480` */ maxBytes?: number; /** From 8d02fa01a8d2bf9eb6cc4bf23f6a4f99ee2d99cc Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:08:19 +0000 Subject: [PATCH 4/8] Specify default values in types --- packages/logger/src/types/Logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/logger/src/types/Logger.ts b/packages/logger/src/types/Logger.ts index f326f2e538..819f35d898 100644 --- a/packages/logger/src/types/Logger.ts +++ b/packages/logger/src/types/Logger.ts @@ -184,7 +184,6 @@ type LogBufferOption = { * Whether logs should be buffered */ enabled?: boolean; - /** * Maximum size of the buffer in bytes * @default `20480` @@ -192,11 +191,13 @@ type LogBufferOption = { maxBytes?: number; /** * Flush the buffer when an error is logged + * @default `true` */ flushOnErrorLog?: boolean; /** * The threshold to buffer logs. Logs with a level below * this threshold will be buffered + * @default `'DEBUG'` */ bufferAtVerbosity?: Omit< LogLevel, From 6c3bac786d324ffa1cab20913cda2ee05677a418 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:08:26 +0000 Subject: [PATCH 5/8] Fix tests --- packages/logger/tests/unit/logBuffer.test.ts | 25 ++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 026449c588..82e37cdc19 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -39,7 +39,11 @@ describe('Log Buffer', () => { it('sets a max buffer sized when specified', () => { // Prepare const logger = new TestLogger({ - logBufferOptions: { maxBytes: 250, bufferAtVerbosity: LogLevel.DEBUG }, + logBufferOptions: { + maxBytes: 250, + bufferAtVerbosity: LogLevel.DEBUG, + enabled: true, + }, }); // Act @@ -73,7 +77,7 @@ describe('Log Buffer', () => { it('outputs a warning when there is an error buffering the log', () => { // Prepare process.env.POWERTOOLS_DEV = 'true'; - const logger = new TestLogger(); + const logger = new TestLogger({ logBufferOptions: { enabled: true } }); logger.overrideBufferLogItem(); // Act @@ -88,7 +92,10 @@ describe('Log Buffer', () => { // Prepare const logger = new TestLogger({ logLevel: 'SILENT', - logBufferOptions: { bufferAtVerbosity: LogLevel.CRITICAL }, + logBufferOptions: { + enabled: true, + bufferAtVerbosity: LogLevel.CRITICAL, + }, }); // Act @@ -110,7 +117,7 @@ describe('Log Buffer', () => { it('handles an empty buffer', () => { // Prepare - const logger = new TestLogger(); + const logger = new TestLogger({ logBufferOptions: { enabled: true } }); // Act logger.flushBuffer(); @@ -119,7 +126,7 @@ describe('Log Buffer', () => { it('does not output buffered logs when trace id is not set', () => { // Prepare process.env._X_AMZN_TRACE_ID = undefined; - const logger = new TestLogger({}); + const logger = new TestLogger({ logBufferOptions: { enabled: true } }); // Act logger.debug('This is a debug'); @@ -141,7 +148,11 @@ describe('Log Buffer', () => { // Prepare const logger = new TestLogger({ logLevel: LogLevel.ERROR, - logBufferOptions: { bufferAtVerbosity: LogLevel.INFO }, + logBufferOptions: { + enabled: true, + bufferAtVerbosity: LogLevel.INFO, + maxBytes: 1024, + }, }); // Act @@ -172,7 +183,7 @@ describe('Log Buffer', () => { // Prepare const logger = new TestLogger({ logLevel: LogLevel.ERROR, - logBufferOptions: { bufferAtVerbosity: LogLevel.DEBUG }, + logBufferOptions: { enabled: true, bufferAtVerbosity: LogLevel.DEBUG }, }); const spy = vi.spyOn(logger, 'flushBuffer'); From ffc4194a36b143babeac164d02674a6728e99828 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:19:13 +0000 Subject: [PATCH 6/8] Remove unused return statement --- packages/logger/src/Logger.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index be16b00a5b..895cb4600b 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1253,8 +1253,6 @@ class Logger extends Utility implements LoggerInterface { if (this.isValidLogLevel(bufferAtLogLevel)) { this.bufferAtVerbosity = LogLevelThreshold[bufferAtLogLevel]; - - return; } } From 4cc48f6987a3ea77e8aea849aed4bfa6a59898a0 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 10:39:01 +0000 Subject: [PATCH 7/8] Enable log buffering when config object is present --- packages/logger/src/Logger.ts | 7 ++++--- packages/logger/tests/unit/logBuffer.test.ts | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 895cb4600b..537df3e39a 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1245,10 +1245,11 @@ class Logger extends Utility implements LoggerInterface { maxBytesSize: this.#maxBufferBytesSize, }); - if (options.enabled !== undefined) { - this.isBufferEnabled = options.enabled; + if (options.enabled === false) { + this.isBufferEnabled = false; + } else { + this.isBufferEnabled = true; } - const bufferAtLogLevel = options.bufferAtVerbosity?.toUpperCase(); if (this.isValidLogLevel(bufferAtLogLevel)) { diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 82e37cdc19..05df923c7f 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -36,6 +36,20 @@ describe('Log Buffer', () => { expect(console.debug).toBeCalledTimes(0); }); + it('buffers logs when the config object is provided, but not specifically enabled', () => { + // Prepare + const logger = new TestLogger({ + logLevel: LogLevel.ERROR, + logBufferOptions: { maxBytes: 100 }, + }); + + // Act + logger.debug('This is a log message'); + logger.flushBuffer(); + // Assess + expect(console.debug).toBeCalledTimes(1); + }); + it('sets a max buffer sized when specified', () => { // Prepare const logger = new TestLogger({ From 4f4db708f394532a8a2cb8b68af061b4a6f3e2f1 Mon Sep 17 00:00:00 2001 From: Connor Kirkpatrick Date: Tue, 25 Feb 2025 11:21:56 +0000 Subject: [PATCH 8/8] Fix flushOnErrorLog config --- packages/logger/src/Logger.ts | 6 ++++++ packages/logger/tests/unit/logBuffer.test.ts | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index 537df3e39a..8324e29196 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -1250,6 +1250,12 @@ class Logger extends Utility implements LoggerInterface { } else { this.isBufferEnabled = true; } + + if (options.flushOnErrorLog === false) { + this.flushOnErrorLog = false; + } else { + this.flushOnErrorLog = true; + } const bufferAtLogLevel = options.bufferAtVerbosity?.toUpperCase(); if (this.isValidLogLevel(bufferAtLogLevel)) { diff --git a/packages/logger/tests/unit/logBuffer.test.ts b/packages/logger/tests/unit/logBuffer.test.ts index 05df923c7f..f7e4558c73 100644 --- a/packages/logger/tests/unit/logBuffer.test.ts +++ b/packages/logger/tests/unit/logBuffer.test.ts @@ -36,6 +36,21 @@ describe('Log Buffer', () => { expect(console.debug).toBeCalledTimes(0); }); + it('does not flush on error logs when flushOnErrorLog is disabled ', () => { + // Prepare + const logger = new TestLogger({ + logLevel: LogLevel.ERROR, + logBufferOptions: { enabled: true, flushOnErrorLog: false }, + }); + + // Act + logger.debug('This is a log message'); + logger.error('This is an error message'); + // Assess + expect(console.debug).toBeCalledTimes(0); + expect(console.error).toBeCalledTimes(1); + }); + it('buffers logs when the config object is provided, but not specifically enabled', () => { // Prepare const logger = new TestLogger({