From 3be8ea86f7b04fee6c0601e00946cc260153ed68 Mon Sep 17 00:00:00 2001 From: Jens-Uwe Mager Date: Tue, 7 Jan 2025 14:38:37 +0100 Subject: [PATCH 1/6] Add a settings option to log to console in json format. For deployments in docker containers it is very useful to just log to console in a structured json format without any color escapes. This adds the advanced option log_console_json (default false) to enable this. --- lib/types/types.d.ts | 1 + lib/util/logger.ts | 16 ++++++++++------ lib/util/settings.schema.json | 7 +++++++ lib/util/settings.ts | 1 + 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/types/types.d.ts b/lib/types/types.d.ts index 86220707a0..b3158b4359 100644 --- a/lib/types/types.d.ts +++ b/lib/types/types.d.ts @@ -168,6 +168,7 @@ declare global { device_options: KeyValue; advanced: { log_rotation: boolean; + log_console_json: boolean; log_symlink_current: boolean; log_output: ('console' | 'file' | 'syslog')[]; log_directory: string; diff --git a/lib/util/logger.ts b/lib/util/logger.ts index 25dca6029d..6db1cebedd 100644 --- a/lib/util/logger.ts +++ b/lib/util/logger.ts @@ -53,16 +53,20 @@ class Logger { let logging = `Logging to console${consoleSilenced ? ' (silenced)' : ''}`; // Setup default console logger - this.logger.add( - new winston.transports.Console({ - silent: consoleSilenced, - // winston.config.syslog.levels sets 'warning' as 'red' - format: winston.format.combine( + // winston.config.syslog.levels sets 'warning' as 'red' + let console_format = winston.format.combine( winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}), winston.format.printf((info) => { return `[${info.timestamp}] ${info.level}: \t${info.message}`; }), - ), + ) + if (settings.get().advanced.log_console_json) { + console_format = winston.format.json() + } + this.logger.add( + new winston.transports.Console({ + silent: consoleSilenced, + format: console_format }), ); diff --git a/lib/util/settings.schema.json b/lib/util/settings.schema.json index 7aa3eb207d..dc7ef0366a 100644 --- a/lib/util/settings.schema.json +++ b/lib/util/settings.schema.json @@ -452,6 +452,13 @@ "description": "Log rotation", "default": true }, + "log_console_json": { + "type": "boolean", + "title": "Console json log", + "requiresRestart": true, + "description": "Console json log", + "default": false + }, "log_symlink_current": { "type": "boolean", "title": "Log symlink current", diff --git a/lib/util/settings.ts b/lib/util/settings.ts index c236ee3880..db53afc269 100644 --- a/lib/util/settings.ts +++ b/lib/util/settings.ts @@ -86,6 +86,7 @@ export const defaults: RecursivePartial = { device_options: {}, advanced: { log_rotation: true, + log_console_json: false, log_symlink_current: false, log_output: ['console', 'file'], log_directory: path.join(data.getPath(), 'log', '%TIMESTAMP%'), From 1c27a1293512949ce0efc83b51a7ef417aab131b Mon Sep 17 00:00:00 2001 From: Jens-Uwe Mager Date: Tue, 7 Jan 2025 14:54:34 +0100 Subject: [PATCH 2/6] Run prettier. --- lib/util/logger.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/util/logger.ts b/lib/util/logger.ts index 6db1cebedd..27b05ebe22 100644 --- a/lib/util/logger.ts +++ b/lib/util/logger.ts @@ -53,20 +53,20 @@ class Logger { let logging = `Logging to console${consoleSilenced ? ' (silenced)' : ''}`; // Setup default console logger - // winston.config.syslog.levels sets 'warning' as 'red' - let console_format = winston.format.combine( - winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}), - winston.format.printf((info) => { - return `[${info.timestamp}] ${info.level}: \t${info.message}`; - }), - ) - if (settings.get().advanced.log_console_json) { - console_format = winston.format.json() - } + // winston.config.syslog.levels sets 'warning' as 'red' + let console_format = winston.format.combine( + winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}), + winston.format.printf((info) => { + return `[${info.timestamp}] ${info.level}: \t${info.message}`; + }), + ); + if (settings.get().advanced.log_console_json) { + console_format = winston.format.json(); + } this.logger.add( new winston.transports.Console({ silent: consoleSilenced, - format: console_format + format: console_format, }), ); From b431397ece2cc462160839ff106902d85db25a11 Mon Sep 17 00:00:00 2001 From: Nerivec <62446222+Nerivec@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:13:29 +0100 Subject: [PATCH 3/6] cleanup --- lib/util/logger.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/util/logger.ts b/lib/util/logger.ts index 27b05ebe22..03aebf3c3d 100644 --- a/lib/util/logger.ts +++ b/lib/util/logger.ts @@ -53,20 +53,18 @@ class Logger { let logging = `Logging to console${consoleSilenced ? ' (silenced)' : ''}`; // Setup default console logger - // winston.config.syslog.levels sets 'warning' as 'red' - let console_format = winston.format.combine( - winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}), - winston.format.printf((info) => { - return `[${info.timestamp}] ${info.level}: \t${info.message}`; - }), - ); - if (settings.get().advanced.log_console_json) { - console_format = winston.format.json(); - } this.logger.add( new winston.transports.Console({ silent: consoleSilenced, - format: console_format, + format: settings.get().advanced.log_console_json + ? winston.format.json() + : winston.format.combine( + // winston.config.syslog.levels sets 'warning' as 'red' + winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}), + winston.format.printf((info) => { + return `[${info.timestamp}] ${info.level}: \t${info.message}`; + }), + ), }), ); From 0874865c5858f147b48bde8bb124420882feadb0 Mon Sep 17 00:00:00 2001 From: Nerivec <62446222+Nerivec@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:31:55 +0100 Subject: [PATCH 4/6] fix test --- test/extensions/bridge.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/extensions/bridge.test.ts b/test/extensions/bridge.test.ts index d345481c85..5172de4c9c 100644 --- a/test/extensions/bridge.test.ts +++ b/test/extensions/bridge.test.ts @@ -118,6 +118,7 @@ describe('Extension: Bridge', () => { log_level: 'info', log_namespaced_levels: {}, log_output: ['console', 'file'], + log_console_json: false, log_rotation: true, log_symlink_current: false, log_syslog: {}, From 4a37f8c11c3df477abe5b440ae7f5992d4f72171 Mon Sep 17 00:00:00 2001 From: Nerivec <62446222+Nerivec@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:33:58 +0100 Subject: [PATCH 5/6] add coverage --- test/logger.test.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/logger.test.ts b/test/logger.test.ts index 4420844300..4b439ce6c5 100644 --- a/test/logger.test.ts +++ b/test/logger.test.ts @@ -397,4 +397,27 @@ describe('Logger', () => { expect(logSpy).toHaveBeenLastCalledWith('debug', `z2m:test: ${splatChars}`); expect(consoleWriteSpy.mock.calls[1][0]).toMatch(new RegExp(`^.*\tz2m:test: ${splatChars}`)); }); + + it('Logs to console in JSON when configured', () => { + settings.set(['advanced', 'log_console_json'], true); + logger.init(); + + consoleWriteSpy.mockClear(); + logger.info(`Test JSON message`, 'z2m'); + + const outputJSON = JSON.parse(consoleWriteSpy.mock.calls[0][0]); + expect(outputJSON).toStrictEqual({ + level: 'info', + message: 'z2m: Test JSON message', + timestamp: expect.any(String), + }); + + settings.set(['advanced', 'log_console_json'], false); + logger.init(); + + consoleWriteSpy.mockClear(); + logger.info(`Test JSON message`, 'z2m'); + + expect(consoleWriteSpy.mock.calls[0][0].endsWith('info: z2m: Test JSON message\r\n')).toStrictEqual(true); + }); }); From 2db1c2ad4764f33f40a4dfa20942d09faa62236b Mon Sep 17 00:00:00 2001 From: Nerivec <62446222+Nerivec@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:40:22 +0100 Subject: [PATCH 6/6] fix cross-platform --- test/logger.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/logger.test.ts b/test/logger.test.ts index 4b439ce6c5..a193ab7835 100644 --- a/test/logger.test.ts +++ b/test/logger.test.ts @@ -418,6 +418,7 @@ describe('Logger', () => { consoleWriteSpy.mockClear(); logger.info(`Test JSON message`, 'z2m'); - expect(consoleWriteSpy.mock.calls[0][0].endsWith('info: z2m: Test JSON message\r\n')).toStrictEqual(true); + const outputStr: string = consoleWriteSpy.mock.calls[0][0]; + expect(outputStr.trim().endsWith('\u001b[32minfo\u001b[39m: \tz2m: Test JSON message')).toStrictEqual(true); }); });