From 121fd52ddfbb0dfe252f7038cdff990c8b1a5c54 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 19 Feb 2024 14:41:41 +0100 Subject: [PATCH 01/10] fix: create custom logs cleanup function Ref: #3609 --- api/lib/logger.ts | 125 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index ce2a158f02..0fd71a398d 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -1,10 +1,13 @@ -import DailyRotateFile from '@zwave-js/winston-daily-rotate-file' +import DailyRotateFile, { + DailyRotateFileTransportOptions, +} from '@zwave-js/winston-daily-rotate-file' import { ensureDirSync } from 'fs-extra' import winston from 'winston' import { logsDir, storeDir } from '../config/app' import { GatewayConfig } from './Gateway' import { DeepPartial, joinPath } from './utils' import * as path from 'path' +import { readdir, stat, unlink } from 'fs/promises' const { format, transports, addColors } = winston const { combine, timestamp, label, printf, colorize, splat } = format @@ -121,7 +124,7 @@ export function customTransports(config: LoggerConfig): winston.transport[] { level: config.level, }) } else { - fileTransport = new DailyRotateFile({ + const options: DailyRotateFileTransportOptions = { filename: config.filePath, auditFile: joinPath(logsDir, 'zui-logs.audit.json'), datePattern: 'YYYY-MM-DD', @@ -134,7 +137,10 @@ export function customTransports(config: LoggerConfig): winston.transport[] { maxSize: process.env.ZUI_LOG_MAXSIZE || '50m', level: config.level, format: customFormat(config, true), - }) + } + fileTransport = new DailyRotateFile(options) + + setupCleanJob(options) } transportsList.push(fileTransport) @@ -177,9 +183,122 @@ export function module(module: string): ModuleLogger { * Setup all loggers starting from config */ export function setupAll(config: DeepPartial) { + if (cleanJob) { + clearInterval(cleanJob) + cleanJob = undefined + } + logContainer.loggers.forEach((logger: ModuleLogger) => { logger.setup(config) }) } +let cleanJob: NodeJS.Timeout + +function setupCleanJob(settings: DailyRotateFileTransportOptions) { + if (cleanJob) { + return + } + + let maxFilesMs: number + let maxFiles: number + let maxSizeBytes: number + + const logger = module('LOGGER') + + // convert maxFiles to milliseconds + if (settings.maxFiles !== undefined) { + const matches = settings.maxFiles.toString().match(/(\d+)([dhm])/) + + if (settings.maxFiles) { + const value = parseInt(matches[1]) + const unit = matches[2] + switch (unit) { + case 'd': + maxFilesMs = value * 24 * 60 * 60 * 1000 + break + case 'h': + maxFilesMs = value * 60 * 60 * 1000 + break + case 'm': + maxFilesMs = value * 60 * 1000 + break + } + } else { + maxFiles = Number(settings.maxFiles) + } + } + + if (settings.maxSize !== undefined) { + // convert maxSize to bytes + const matches2 = settings.maxSize.toString().match(/(\d+)([kmg])/) + if (matches2) { + const value = parseInt(matches2[1]) + const unit = matches2[2] + switch (unit) { + case 'k': + maxSizeBytes = value * 1024 + break + case 'm': + maxSizeBytes = value * 1024 * 1024 + break + case 'g': + maxSizeBytes = value * 1024 * 1024 * 1024 + break + } + } else { + maxSizeBytes = Number(settings.maxSize) + } + } + + // clean up old log files based on maxFiles and maxSize + + const filePathRegExp = new RegExp( + path.basename(settings.filename).replace(/%DATE%/g, '([^.]+)'), + ) + + const logsDir = path.dirname(settings.filename) + + const clean = async () => { + try { + logger.info('Cleaning up log files...') + const files = await readdir(logsDir) + const logFiles = files.filter( + (file) => + file !== settings.symlinkName && filePathRegExp.test(file), + ) + logFiles.sort() + + let totalSize = 0 + let deletedFiles = 0 + for (const file of logFiles) { + const filePath = path.join(logsDir, file) + const stats = await stat(filePath) + totalSize += stats.size + const fileDateStr = file.match(filePathRegExp) + + const fileMs = fileDateStr[1] + ? new Date(fileDateStr[1]).getTime() + : 0 + + const shouldDelete = + (maxSizeBytes && totalSize > maxSizeBytes) || + (maxFiles && logFiles.length - deletedFiles > maxFiles) || + (maxFilesMs && fileMs && Date.now() - fileMs > maxFilesMs) + + if (shouldDelete) { + logger.info(`Deleting log file: ${filePath}`) + await unlink(filePath) + deletedFiles++ + } + } + } catch (e) { + console.error('Error cleaning up log files:', e) + } + } + + cleanJob = setInterval(clean, 60 * 60 * 1000) + clean().catch(() => {}) +} + export default logContainer.loggers From 76370e1f637b52d73500f567ba70e3c0bdb361a9 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 19 Feb 2024 15:09:18 +0100 Subject: [PATCH 02/10] fix: use mtime --- api/lib/logger.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 0fd71a398d..6b0ff32fbc 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -267,19 +267,25 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { (file) => file !== settings.symlinkName && filePathRegExp.test(file), ) - logFiles.sort() + + const logFilesStats = await Promise.all( + logFiles.map(async (file) => ({ + file, + stats: await stat(path.join(logsDir, file)), + })), + ) + + logFilesStats.sort((a, b) => a.stats.mtimeMs - b.stats.mtimeMs) + + // sort by mtime let totalSize = 0 let deletedFiles = 0 - for (const file of logFiles) { + for (const { file, stats } of logFilesStats) { const filePath = path.join(logsDir, file) - const stats = await stat(filePath) totalSize += stats.size - const fileDateStr = file.match(filePathRegExp) - const fileMs = fileDateStr[1] - ? new Date(fileDateStr[1]).getTime() - : 0 + const fileMs = stats.mtimeMs const shouldDelete = (maxSizeBytes && totalSize > maxSizeBytes) || From a8f9c8d42811b4f8f772ed4eb0771427b63da037 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 19 Feb 2024 15:55:32 +0100 Subject: [PATCH 03/10] fix: catch unlink errors --- api/lib/logger.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 6b0ff32fbc..437095f684 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -259,6 +259,13 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { const logsDir = path.dirname(settings.filename) + const deleteFile = async (filePath: string) => { + logger.info(`Deleting log file: ${filePath}`) + return unlink(filePath).catch((e) => { + logger.error(`Error deleting log file: ${filePath}`, e) + }) + } + const clean = async () => { try { logger.info('Cleaning up log files...') @@ -285,6 +292,7 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { const filePath = path.join(logsDir, file) totalSize += stats.size + // last modified time in milliseconds const fileMs = stats.mtimeMs const shouldDelete = @@ -293,13 +301,12 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { (maxFilesMs && fileMs && Date.now() - fileMs > maxFilesMs) if (shouldDelete) { - logger.info(`Deleting log file: ${filePath}`) - await unlink(filePath) + await deleteFile(filePath) deletedFiles++ } } } catch (e) { - console.error('Error cleaning up log files:', e) + logger.error('Error cleaning up log files:', e) } } From d851fa9cccd70c3ec2bf6e28f9f52b3f7b3e3685 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 19 Feb 2024 16:06:19 +0100 Subject: [PATCH 04/10] fix: only log errors !== ENOENT --- api/lib/logger.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 437095f684..6b50857a35 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -262,7 +262,9 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { const deleteFile = async (filePath: string) => { logger.info(`Deleting log file: ${filePath}`) return unlink(filePath).catch((e) => { - logger.error(`Error deleting log file: ${filePath}`, e) + if (e.code !== 'ENOENT') { + logger.error(`Error deleting log file: ${filePath}`, e) + } }) } From 471a55048eb1fd7eb843c827099938df78c33796 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Mon, 19 Feb 2024 16:17:36 +0100 Subject: [PATCH 05/10] fix: ensure stat doesn't throw --- api/lib/logger.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 6b50857a35..cdbd1e3514 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -8,6 +8,8 @@ import { GatewayConfig } from './Gateway' import { DeepPartial, joinPath } from './utils' import * as path from 'path' import { readdir, stat, unlink } from 'fs/promises' +import { log } from 'console' +import { Stats } from 'fs' const { format, transports, addColors } = winston const { combine, timestamp, label, printf, colorize, splat } = format @@ -277,13 +279,29 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { file !== settings.symlinkName && filePathRegExp.test(file), ) - const logFilesStats = await Promise.all( + const fileStats = await Promise.allSettled<{ + file: string + stats: Stats + }>( logFiles.map(async (file) => ({ file, stats: await stat(path.join(logsDir, file)), })), ) + const logFilesStats: { + file: string + stats: Stats + }[] = [] + + for (const res of fileStats) { + if (res.status === 'fulfilled') { + logFilesStats.push(res.value) + } else { + logger.error('Error getting file stats:', res.reason) + } + } + logFilesStats.sort((a, b) => a.stats.mtimeMs - b.stats.mtimeMs) // sort by mtime From 82c1f8d7a00c1563194149efbccab648f20fd62d Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Tue, 20 Feb 2024 08:59:38 +0100 Subject: [PATCH 06/10] fix: create stronger regex --- api/lib/logger.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index cdbd1e3514..701f3f0c21 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -8,7 +8,6 @@ import { GatewayConfig } from './Gateway' import { DeepPartial, joinPath } from './utils' import * as path from 'path' import { readdir, stat, unlink } from 'fs/promises' -import { log } from 'console' import { Stats } from 'fs' const { format, transports, addColors } = winston @@ -256,7 +255,7 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { // clean up old log files based on maxFiles and maxSize const filePathRegExp = new RegExp( - path.basename(settings.filename).replace(/%DATE%/g, '([^.]+)'), + path.basename(settings.filename).replace(/%DATE%/g, '(.*)'), ) const logsDir = path.dirname(settings.filename) From 27ea06ceb32484a0507ff716e0d2e4b197c0065a Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Tue, 20 Feb 2024 09:08:49 +0100 Subject: [PATCH 07/10] fix: logs regex --- api/lib/logger.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 701f3f0c21..15d3a0a2cb 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -255,7 +255,10 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { // clean up old log files based on maxFiles and maxSize const filePathRegExp = new RegExp( - path.basename(settings.filename).replace(/%DATE%/g, '(.*)'), + path + .basename(settings.filename) + .replace(/\./g, '\\.') // here we should escape every possible regex character, but for now we just escape the dot + .replace(/%DATE%/g, '(.*)'), ) const logsDir = path.dirname(settings.filename) From 227981c8a6fdc8daa1594a97ebf9a5a009d5746b Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Tue, 20 Feb 2024 09:11:28 +0100 Subject: [PATCH 08/10] fix: use escape-string-regex --- api/lib/logger.ts | 9 +++++---- package-lock.json | 43 ++++++++++++++++++++++++++----------------- package.json | 1 + 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index 15d3a0a2cb..a69fcecbf2 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -9,6 +9,7 @@ import { DeepPartial, joinPath } from './utils' import * as path from 'path' import { readdir, stat, unlink } from 'fs/promises' import { Stats } from 'fs' +import escapeStringRegexp from 'escape-string-regexp' const { format, transports, addColors } = winston const { combine, timestamp, label, printf, colorize, splat } = format @@ -255,10 +256,10 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { // clean up old log files based on maxFiles and maxSize const filePathRegExp = new RegExp( - path - .basename(settings.filename) - .replace(/\./g, '\\.') // here we should escape every possible regex character, but for now we just escape the dot - .replace(/%DATE%/g, '(.*)'), + escapeStringRegexp(path.basename(settings.filename)).replace( + /%DATE%/g, + '(.*)', + ), ) const logsDir = path.dirname(settings.filename) diff --git a/package-lock.json b/package-lock.json index 95e9b3da85..44c540e2c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "cronstrue": "^2.32.0", "csurf": "^1.11.0", "dotenv": "^16.3.1", + "escape-string-regexp": "^5.0.0", "express": "^4.18.2", "express-rate-limit": "^7.1.1", "express-session": "^1.17.3", @@ -6051,6 +6052,15 @@ "node": ">=4" } }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -7984,12 +7994,14 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "engines": { - "node": ">=0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { @@ -8986,18 +8998,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/figures/node_modules/is-unicode-supported": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", @@ -19921,6 +19921,15 @@ "node": ">=0.10.0" } }, + "node_modules/yargonaut/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/yargonaut/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", diff --git a/package.json b/package.json index ab218f79c8..553675fc0b 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "cronstrue": "^2.32.0", "csurf": "^1.11.0", "dotenv": "^16.3.1", + "escape-string-regexp": "^5.0.0", "express": "^4.18.2", "express-rate-limit": "^7.1.1", "express-session": "^1.17.3", From f18854dc3b3abc9121d71ec06adb59d5c33a3424 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Tue, 20 Feb 2024 09:13:45 +0100 Subject: [PATCH 09/10] fix: downgrade to v4.0 (v5 is pure ESM) --- package-lock.json | 46 +++++++++++++++++----------------------------- package.json | 2 +- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44c540e2c6..0225173344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "cronstrue": "^2.32.0", "csurf": "^1.11.0", "dotenv": "^16.3.1", - "escape-string-regexp": "^5.0.0", + "escape-string-regexp": "^4.0.0", "express": "^4.18.2", "express-rate-limit": "^7.1.1", "express-session": "^1.17.3", @@ -7994,11 +7994,11 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8458,18 +8458,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/globals": { "version": "13.23.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", @@ -8998,6 +8986,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/figures/node_modules/is-unicode-supported": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", @@ -12338,18 +12338,6 @@ "node": ">=6" } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", diff --git a/package.json b/package.json index 553675fc0b..ef4a4c809d 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "cronstrue": "^2.32.0", "csurf": "^1.11.0", "dotenv": "^16.3.1", - "escape-string-regexp": "^5.0.0", + "escape-string-regexp": "^4.0.0", "express": "^4.18.2", "express-rate-limit": "^7.1.1", "express-session": "^1.17.3", From 6169819ef6d4af336df276499607be0b10f8a253 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Thu, 22 Feb 2024 17:43:34 +0100 Subject: [PATCH 10/10] fix: tests --- api/lib/logger.ts | 14 +++++++++----- test/lib/logger.test.ts | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/api/lib/logger.ts b/api/lib/logger.ts index a69fcecbf2..aea668200c 100644 --- a/api/lib/logger.ts +++ b/api/lib/logger.ts @@ -185,10 +185,7 @@ export function module(module: string): ModuleLogger { * Setup all loggers starting from config */ export function setupAll(config: DeepPartial) { - if (cleanJob) { - clearInterval(cleanJob) - cleanJob = undefined - } + stopCleanJob() logContainer.loggers.forEach((logger: ModuleLogger) => { logger.setup(config) @@ -197,7 +194,7 @@ export function setupAll(config: DeepPartial) { let cleanJob: NodeJS.Timeout -function setupCleanJob(settings: DailyRotateFileTransportOptions) { +export function setupCleanJob(settings: DailyRotateFileTransportOptions) { if (cleanJob) { return } @@ -337,4 +334,11 @@ function setupCleanJob(settings: DailyRotateFileTransportOptions) { clean().catch(() => {}) } +export function stopCleanJob() { + if (cleanJob) { + clearInterval(cleanJob) + cleanJob = undefined + } +} + export default logContainer.loggers diff --git a/test/lib/logger.test.ts b/test/lib/logger.test.ts index 6e19dba4bb..631f0d9ddc 100644 --- a/test/lib/logger.test.ts +++ b/test/lib/logger.test.ts @@ -8,6 +8,7 @@ import { sanitizedConfig, module, setupAll, + stopCleanJob, } from '../../api/lib/logger' import winston from 'winston' @@ -23,6 +24,10 @@ describe('logger.js', () => { let logger1: ModuleLogger let logger2: ModuleLogger + afterEach(() => { + stopCleanJob() + }) + describe('sanitizedConfig()', () => { it('should set undefined config object to defaults', () => { const cfg = sanitizedConfig('-', undefined)