diff --git a/lib/categories.js b/lib/categories.js index 5eda7e5..23583ac 100644 --- a/lib/categories.js +++ b/lib/categories.js @@ -194,11 +194,15 @@ const setLevelForCategory = (category, level) => { categories.set(category, categoryConfig); }; -const isCallStackEnable = category => configForCategory(category).enableCallStack === true; +const getEnableCallStackForCategory = category => configForCategory(category).enableCallStack === true; +const setEnableCallStackForCategory = (category, useCallStack) => { + configForCategory(category).enableCallStack = useCallStack; +}; module.exports = { appendersForCategory, getLevelForCategory, setLevelForCategory, - isCallStackEnable, + getEnableCallStackForCategory, + setEnableCallStackForCategory, }; diff --git a/lib/log4js.js b/lib/log4js.js index 51c28d0..f30da14 100644 --- a/lib/log4js.js +++ b/lib/log4js.js @@ -33,16 +33,6 @@ const clustering = require('./clustering'); const connectLogger = require('./connect-logger'); let enabled = false; -let gCallStackEnabled = false; -const loggers = new Map(); - -function useCallStack(bool = true) { - gCallStackEnabled = (bool === true); - - loggers.forEach(logger => logger.enableCallStack(gCallStackEnabled)); - // eslint-disable-next-line no-use-before-define - return log4js; -} function sendLogEventToAppender(logEvent) { if (!enabled) return; @@ -133,15 +123,7 @@ function getLogger(category) { categories: { default: { appenders: ['out'], level: 'OFF' } } }); } - category = category || 'default'; - let logger = loggers.get(category); - if (!logger) { - logger = (new Logger(category)).enableCallStack( - categories.isCallStackEnable(category) || gCallStackEnabled - ); - loggers.set(category, logger); - } - return logger; + return new Logger(category || 'default'); } @@ -159,7 +141,6 @@ const log4js = { connectLogger, levels, addLayout: layouts.addLayout, - useCallStack, }; module.exports = log4js; diff --git a/lib/logger.js b/lib/logger.js index f26dd9a..15e2d24 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -10,7 +10,7 @@ const categories = require('./categories'); const configuration = require('./configuration'); const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/; -function parseStack(data, skipIdx = 4) { +function parseCallStack(data, skipIdx = 4) { const stacklines = data.stack.split('\n').slice(skipIdx); const lineMatch = stackReg.exec(stacklines[0]); if (lineMatch && lineMatch.length === 6) { @@ -25,6 +25,7 @@ function parseStack(data, skipIdx = 4) { return null; } +// const _useCallStack = Symbol('useCallStack'); /** * Logger to log messages. * use {@see log4js#getLogger(String)} to get an instance. @@ -46,7 +47,7 @@ class Logger { this.context = {}; debug(`Logger created (${this.category}, ${this.level})`); - this._useStack = false; + // this[_useCallStack] = false; } get level() { @@ -57,6 +58,16 @@ class Logger { categories.setLevelForCategory(this.category, levels.getLevel(level, this.level)); } + get useCallStack() { + // return this[_useCallStack]; + return categories.getEnableCallStackForCategory(this.category); + } + + set useCallStack(bool) { + // this[_useCallStack] = (bool === true); + categories.setEnableCallStackForCategory(this.category, (bool === true)); + } + log(level, ...args) { const logLevel = levels.getLevel(level, levels.INFO); if (this.isLevelEnabled(logLevel)) { @@ -71,8 +82,8 @@ class Logger { _log(level, data) { debug(`sending log data (${level}) to appenders`); let loggingEvent = null; - if (this._useStack) { - loggingEvent = new LoggingEvent(this.category, level, data, this.context, parseStack(new Error())); + if (this.useCallStack) { + loggingEvent = new LoggingEvent(this.category, level, data, this.context, parseCallStack(new Error())); } else { loggingEvent = new LoggingEvent(this.category, level, data, this.context); } @@ -90,15 +101,6 @@ class Logger { clearContext() { this.context = {}; } - - enableCallStack(bool = true) { - this._useStack = (bool === true); - return this; - } - - isCallStackEnable() { - return this._useStack === true; - } } function addLevelMethods(target) { diff --git a/test/tap/logger-test.js b/test/tap/logger-test.js index fe2237b..7763f6a 100644 --- a/test/tap/logger-test.js +++ b/test/tap/logger-test.js @@ -127,34 +127,40 @@ test('../../lib/logger', (batch) => { t.end(); }); - batch.test('should (default) disable stack trace unless manual enable', (t) => { + batch.test('default should disable useCallStack unless manual enable', (t) => { const logger = new Logger('stack'); logger.level = 'debug'; - t.equal(logger.isCallStackEnable(), false); + t.equal(logger.useCallStack, false); - logger.enableCallStack(false); - t.equal(logger.isCallStackEnable(), false); + logger.useCallStack = false; + t.equal(logger.useCallStack, false); - logger.enableCallStack(0); - t.equal(logger.isCallStackEnable(), false); + logger.useCallStack = 0; + t.equal(logger.useCallStack, false); - logger.enableCallStack(''); - t.equal(logger.isCallStackEnable(), false); + logger.useCallStack = ''; + t.equal(logger.useCallStack, false); - logger.enableCallStack(null); - t.equal(logger.isCallStackEnable(), false); + logger.useCallStack = null; + t.equal(logger.useCallStack, false); - logger.enableCallStack(); - t.equal(logger.isCallStackEnable(), true); + logger.useCallStack = undefined; + t.equal(logger.useCallStack, false); + + logger.useCallStack = 'true'; + t.equal(logger.useCallStack, false); + + logger.useCallStack = true; + t.equal(logger.useCallStack, true); t.end(); }); - batch.test('should enable stack trace for call stack support', (t) => { + batch.test('should correctly switch on/off useCallStack', (t) => { const logger = new Logger('stack'); logger.level = 'debug'; - logger.enableCallStack(); - t.equal(logger.isCallStackEnable(), true); + logger.useCallStack = true; + t.equal(logger.useCallStack, true); logger.info('hello world'); const callsite = callsites()[0]; @@ -165,8 +171,50 @@ test('../../lib/logger', (batch) => { t.equal(events[0].lineNumber, callsite.getLineNumber() - 1); t.equal(events[0].columnNumber, 12); - logger.enableCallStack(false); - t.equal(logger.isCallStackEnable(), false); + logger.useCallStack = false; + logger.info('disabled'); + t.equal(logger.useCallStack, false); + t.equal(events[1].data[0], 'disabled'); + t.equal(events[1].fileName, undefined); + t.equal(events[1].lineNumber, undefined); + t.equal(events[1].columnNumber, undefined); + t.end(); + }); + + batch.test('Once switch on/off useCallStack will apply all same category loggers', (t) => { + const logger1 = new Logger('stack'); + logger1.level = 'debug'; + logger1.useCallStack = true; + const logger2 = new Logger('stack'); + logger2.level = 'debug'; + + logger1.info('hello world'); + const callsite = callsites()[0]; + + t.equal(logger1.useCallStack, true); + t.equal(events.length, 1); + t.equal(events[0].data[0], 'hello world'); + t.equal(events[0].fileName, callsite.getFileName()); + t.equal(events[0].lineNumber, callsite.getLineNumber() - 1); + t.equal(events[0].columnNumber, 13); + + logger2.info('hello world'); + const callsite2 = callsites()[0]; + + t.equal(logger2.useCallStack, true); + t.equal(events[1].data[0], 'hello world'); + t.equal(events[1].fileName, callsite2.getFileName()); + t.equal(events[1].lineNumber, callsite2.getLineNumber() - 1); + t.equal(events[1].columnNumber, 13); + + logger1.useCallStack = false; + logger2.info('hello world'); + t.equal(logger2.useCallStack, false); + t.equal(events[2].data[0], 'hello world'); + t.equal(events[2].fileName, undefined); + t.equal(events[2].lineNumber, undefined); + t.equal(events[2].columnNumber, undefined); + t.end(); }); diff --git a/test/tap/logging-test.js b/test/tap/logging-test.js index eb864d4..5745be2 100644 --- a/test/tap/logging-test.js +++ b/test/tap/logging-test.js @@ -184,34 +184,5 @@ test('log4js', (batch) => { t.end(); }); - batch.test('useCallStack', (t) => { - const log4js = require('../../lib/log4js'); - log4js.configure({ - appenders: { recorder: { type: 'recording' } }, - categories: { - default: { appenders: ['recorder'], level: 'DEBUG' }, - test: { appenders: ['recorder'], level: 'DEBUG' } - } - }); - const logger = log4js.getLogger(); - const loggerT1 = log4js.getLogger('test'); - const loggerT2 = log4js.getLogger('test'); - loggerT1.enableCallStack(true); - t.deepEqual(loggerT1, loggerT2, 'should get the same logger when same category'); - t.equal(logger.isCallStackEnable(), false, 'default enableCallStack should be false'); - - /* eslint-disable max-len */ - log4js.useCallStack(); - t.equal(logger.isCallStackEnable(), true, 'after log.useCallStack() called, all logger enableCallStack should be true'); - t.equal(loggerT1.isCallStackEnable(), true, 'after log.useCallStack() called, all logger enableCallStack should be true'); - - log4js.useCallStack(false); - t.equal(logger.isCallStackEnable(), false, 'after log.useCallStack(false) called, all logger enableCallStack should be false'); - t.equal(loggerT1.isCallStackEnable(), false, 'after log.useCallStack(false) called, all logger enableCallStack should be false'); - /* eslint-enable max-len */ - - t.end(); - }); - batch.end(); });