From aedef32bb9ea8a20011762d03ec24082717dd9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Lef=C3=A8vre?= Date: Mon, 14 Nov 2022 02:13:14 +0100 Subject: [PATCH] feat issue #1341 (Layouts) : support a specifier on %m --- lib/layouts.js | 14 ++++- test/tap/layouts-test.js | 116 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/lib/layouts.js b/lib/layouts.js index 52aef56..2d7c660 100644 --- a/lib/layouts.js +++ b/lib/layouts.js @@ -101,6 +101,8 @@ function dummyLayout(loggingEvent) { * - %c log category * - %h hostname * - %m log data + * - %m{l}, where l is an integer : log data.slice(l) + * - %m{l,u}, where l ans u are integers : log data.slice(l,u) * - %d date in constious formats * - %% % * - %n newline @@ -137,6 +139,8 @@ function patternLayout(pattern, tokens) { const regex = /%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflosCMAF%])(\{([^}]+)\})?|([^%]+)/; + const mSpecifierRegex = /\s*(-?\d)(\s*,\s*(-?\d))?\w*/; + pattern = pattern || TTCC_CONVERSION_PATTERN; function categoryName(loggingEvent, specifier) { @@ -210,8 +214,14 @@ function patternLayout(pattern, tokens) { return os.hostname().toString(); } - function formatMessage(loggingEvent) { - return util.format(...loggingEvent.data); + function formatMessage(loggingEvent, specifier) { + const match = mSpecifierRegex.exec(specifier); + + const lowerBound = match ? parseInt(match[1], 10) : 0; + const upperBound = match && match[3] ? parseInt(match[3], 10) : undefined; + const dataSlice = loggingEvent.data.slice(lowerBound, upperBound); + + return util.format(...dataSlice); } function endOfLine() { diff --git a/test/tap/layouts-test.js b/test/tap/layouts-test.js index e16b83f..a736e5c 100644 --- a/test/tap/layouts-test.js +++ b/test/tap/layouts-test.js @@ -375,6 +375,122 @@ test('log4js layouts', (batch) => { assert.end(); }); + t.test('%m should apply util.format on data', (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like other ones', + "isn't", + 'test', + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m', + "This isn't a test like other ones" + ); + assert.end(); + }); + + t.test( + '%m{P}, with P been an integer, shoud only consider data.slice( P )', + (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like other ones', + "isn't", + 'test', + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m{1}', + "isn't test" + ); + assert.end(); + } + ); + + t.test('%m{0, 1} should behave like a dummy layout', (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like other ones', + "isn't", + 'test', + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m{0, 1}', + 'This %s a %s like other ones' + ); + assert.end(); + }); + + t.test('%m{1, 2} shoud only consider data.slice( 1, 2 )', (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like other ones', + "isn't", + 'test', + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m{1,2}', + "isn't" + ); + assert.end(); + }); + + t.test('%m{1, 2} shoud only consider data.slice( 1, 2 )', (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like other ones', + "isn't", + 'test', + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m{1,2}', + "isn't" + ); + assert.end(); + }); + + t.test( + '%m{0, -1} should consider the whole data except the last element', + (assert) => { + const eventWithSeveralDataEntry = JSON.parse(JSON.stringify(event)); + eventWithSeveralDataEntry.data = [ + 'This %s a %s like %s ones', + "isn't", + 'test', + 'other', + "won't be considered in call to util.format", + ]; + testPattern( + assert, + layout, + eventWithSeveralDataEntry, + tokens, + '%m{0,-1}', + "This isn't a test like other ones" + ); + assert.end(); + } + ); + t.test('%n should output a new line', (assert) => { testPattern(assert, layout, event, tokens, '%n', EOL); assert.end();