From d42b6fd80f7e60a877913de3f10daf46754427b9 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 7 Oct 2024 10:04:57 +0200 Subject: [PATCH 1/4] fix: re-use file transport instance when setup loggers Fixes #2937 --- api/lib/logger.ts | 56 +++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 0d053c0ecc..dcad7a741b 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -19,6 +19,8 @@ export const defaultLogFile = 'z-ui_%DATE%.log' export const disableColors = process.env.NO_LOG_COLORS === 'true' +let fileTransport: winston.transport = null + // ensure store and logs directories exist ensureDirSync(storeDir) ensureDirSync(logsDir) @@ -130,31 +132,33 @@ export function customTransports(config: LoggerConfig): winston.transport[] { transportsList.push(streamTransport) if (config.logToFile) { - let fileTransport: winston.transport - if (process.env.DISABLE_LOG_ROTATION === 'true') { - fileTransport = new transports.File({ - format: customFormat(config, true), - filename: config.filePath, - level: config.level, - }) - } else { - const options: DailyRotateFileTransportOptions = { - filename: config.filePath, - auditFile: joinPath(logsDir, 'zui-logs.audit.json'), - datePattern: 'YYYY-MM-DD', - createSymlink: true, - symlinkName: path - .basename(config.filePath) - .replace(`_%DATE%`, '_current'), - zippedArchive: true, - maxFiles: process.env.ZUI_LOG_MAXFILES || '7d', - maxSize: process.env.ZUI_LOG_MAXSIZE || '50m', - level: config.level, - format: customFormat(config, true), - } - fileTransport = new DailyRotateFile(options) + // setup file transport only once (see issue #2937) + if (!fileTransport) { + if (process.env.DISABLE_LOG_ROTATION === 'true') { + fileTransport = new transports.File({ + format: customFormat(config, true), + filename: config.filePath, + level: config.level, + }) + } else { + const options: DailyRotateFileTransportOptions = { + filename: config.filePath, + auditFile: joinPath(logsDir, 'zui-logs.audit.json'), + datePattern: 'YYYY-MM-DD', + createSymlink: true, + symlinkName: path + .basename(config.filePath) + .replace(`_%DATE%`, '_current'), + zippedArchive: true, + maxFiles: process.env.ZUI_LOG_MAXFILES || '7d', + maxSize: process.env.ZUI_LOG_MAXSIZE || '50m', + level: config.level, + format: customFormat(config, true), + } + fileTransport = new DailyRotateFile(options) - setupCleanJob(options) + setupCleanJob(options) + } } transportsList.push(fileTransport) @@ -199,6 +203,10 @@ export function module(module: string): ModuleLogger { export function setupAll(config: DeepPartial) { stopCleanJob() + fileTransport.close() + + fileTransport = null + logContainer.loggers.forEach((logger: ModuleLogger) => { logger.setup(config) }) From d165b2d707ac685690a42a267733759ededa8ab9 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 7 Oct 2024 13:52:50 +0200 Subject: [PATCH 2/4] fix: extend to all transports --- api/lib/logger.ts | 65 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index dcad7a741b..922cb44f4c 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -19,7 +19,7 @@ export const defaultLogFile = 'z-ui_%DATE%.log' export const disableColors = process.env.NO_LOG_COLORS === 'true' -let fileTransport: winston.transport = null +let transportsList: winston.transport[] = null // ensure store and logs directories exist ensureDirSync(storeDir) @@ -111,7 +111,12 @@ export const logStream = new PassThrough() * Create the base transports based on settings provided */ export function customTransports(config: LoggerConfig): winston.transport[] { - const transportsList: winston.transport[] = [] + // setup transports only once (see issue #2937) + if (transportsList) { + return transportsList + } + + transportsList = [] if (process.env.ZUI_NO_CONSOLE !== 'true') { transportsList.push( @@ -132,37 +137,37 @@ export function customTransports(config: LoggerConfig): winston.transport[] { transportsList.push(streamTransport) if (config.logToFile) { - // setup file transport only once (see issue #2937) - if (!fileTransport) { - if (process.env.DISABLE_LOG_ROTATION === 'true') { - fileTransport = new transports.File({ - format: customFormat(config, true), - filename: config.filePath, - level: config.level, - }) - } else { - const options: DailyRotateFileTransportOptions = { - filename: config.filePath, - auditFile: joinPath(logsDir, 'zui-logs.audit.json'), - datePattern: 'YYYY-MM-DD', - createSymlink: true, - symlinkName: path - .basename(config.filePath) - .replace(`_%DATE%`, '_current'), - zippedArchive: true, - maxFiles: process.env.ZUI_LOG_MAXFILES || '7d', - maxSize: process.env.ZUI_LOG_MAXSIZE || '50m', - level: config.level, - format: customFormat(config, true), - } - fileTransport = new DailyRotateFile(options) + let fileTransport: winston.transport - setupCleanJob(options) + if (process.env.DISABLE_LOG_ROTATION === 'true') { + fileTransport = new transports.File({ + format: customFormat(config, true), + filename: config.filePath, + level: config.level, + }) + } else { + const options: DailyRotateFileTransportOptions = { + filename: config.filePath, + auditFile: joinPath(logsDir, 'zui-logs.audit.json'), + datePattern: 'YYYY-MM-DD', + createSymlink: true, + symlinkName: path + .basename(config.filePath) + .replace(`_%DATE%`, '_current'), + zippedArchive: true, + maxFiles: process.env.ZUI_LOG_MAXFILES || '7d', + maxSize: process.env.ZUI_LOG_MAXSIZE || '50m', + level: config.level, + format: customFormat(config, true), } + fileTransport = new DailyRotateFile(options) + + setupCleanJob(options) } transportsList.push(fileTransport) } + return transportsList } @@ -203,9 +208,11 @@ export function module(module: string): ModuleLogger { export function setupAll(config: DeepPartial) { stopCleanJob() - fileTransport.close() + transportsList.forEach((t) => { + t.close() + }) - fileTransport = null + transportsList = null logContainer.loggers.forEach((logger: ModuleLogger) => { logger.setup(config) From 4a6a22e4f598c7dd011f158bec7bae0f8c75821a Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 7 Oct 2024 16:16:58 +0200 Subject: [PATCH 3/4] fix: tests --- api/lib/logger.ts | 4 +++- test/lib/logger.test.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 922cb44f4c..80f386ee46 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -209,7 +209,9 @@ export function setupAll(config: DeepPartial) { stopCleanJob() transportsList.forEach((t) => { - t.close() + if (typeof t.close === 'function') { + t.close() + } }) transportsList = null diff --git a/test/lib/logger.test.ts b/test/lib/logger.test.ts index 0442f8b07e..394e2b4603 100644 --- a/test/lib/logger.test.ts +++ b/test/lib/logger.test.ts @@ -93,7 +93,7 @@ describe('logger.js', () => { it('should change the log level', () => expect(logger1.level).to.equal('warn')) it('should have 2 transports', () => - expect(logger1.transports.length).to.be.equal(3)) + expect(logger1.transports.length).to.be.equal(2)) }) describe('setup() (reconfigure)', () => { @@ -118,7 +118,7 @@ describe('logger.js', () => { // Test post-conditions: expect(logger1.module).to.equal('mod') expect(logger1.level).to.equal('error') - expect(logger1.transports.length).to.be.equal(3) + expect(logger1.transports.length).to.be.equal(2) }) }) From a1b2e21a2f6c3256d688822a402c9ecdccdf4d29 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Thu, 17 Oct 2024 11:57:04 +0200 Subject: [PATCH 4/4] fix: prevent max listeners warning --- api/lib/logger.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 80f386ee46..4a2d2fa22a 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -168,6 +168,12 @@ export function customTransports(config: LoggerConfig): winston.transport[] { transportsList.push(fileTransport) } + // giving that we re-use transports, each module will subscribe to events + // increeasing the default limit of 100 prevents warnings + transportsList.forEach((t) => { + t.setMaxListeners(100) + }) + return transportsList }