diff --git a/docs/api.md b/docs/api.md index 7ae3c6f..bc4aaaf 100644 --- a/docs/api.md +++ b/docs/api.md @@ -10,6 +10,8 @@ If you are using `cluster`, then include the call to `configure` in the worker p Configuration objects must define at least one appender, and a default category. Log4js will throw an exception if the configuration is invalid. +`configure` method call returns the configured log4js object. + ### Configuration Object Properties: * `levels` (optional, object) - used for defining custom log levels, or redefining existing ones; this is a map with the level name as the key (string, case insensitive), and an object as the value. The object should have two properties: the level value (integer) as the value, and the colour. Log levels are used to assign importance to log messages, with the integer value being used to sort them. If you do not specify anything in your configuration, the default values are used (ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < MARK < OFF - note that OFF is intended to be used to turn off logging, not as a level for actual logging, i.e. you would never call `logger.off('some log message')`). Levels defined here are used in addition to the default levels, with the integer value being used to determine their relation to the default levels. If you define a level with the same name as a default level, then the integer value in the config takes precedence. Level names must begin with a letter, and can only contain letters, numbers and underscores. diff --git a/docs/smtp.md b/docs/smtp.md index d5e0922..b2c7578 100644 --- a/docs/smtp.md +++ b/docs/smtp.md @@ -48,7 +48,7 @@ log4js.configure({ recipients: 'dev.team@company.name', subject: 'Latest logs', sender: 'my.application@company.name', - attachments: { + attachment: { enable: true, filename: 'latest.log', message: 'See the attachment for the latest logs' diff --git a/lib/appenders/redis.js b/lib/appenders/redis.js index 66036ef..41f4341 100644 --- a/lib/appenders/redis.js +++ b/lib/appenders/redis.js @@ -15,7 +15,7 @@ function redisAppender(config, layout) { } }); - return function (loggingEvent) { + const appender = function (loggingEvent) { const message = layout(loggingEvent); redisClient.publish(config.channel, message, (err) => { if (err) { @@ -23,6 +23,13 @@ function redisAppender(config, layout) { } }); }; + + appender.shutdown = (cb) => { + redisClient.quit(); + if (cb) cb(); + }; + + return appender; } function configure(config, layouts) { diff --git a/lib/log4js.js b/lib/log4js.js index 1ef0196..072330d 100644 --- a/lib/log4js.js +++ b/lib/log4js.js @@ -62,6 +62,8 @@ function configure(configurationFileOrObject) { clustering.onMessage(sendLogEventToAppender); enabled = true; + + return log4js; } /** diff --git a/package-lock.json b/package-lock.json index a69ed91..4318ae5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "log4js", - "version": "2.5.2", + "version": "2.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 31991fc..4262ffb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "log4js", - "version": "2.5.2", + "version": "2.5.3", "description": "Port of Log4js to work with node.", "homepage": "https://log4js-node.github.io/log4js-node/", "files": [ diff --git a/test/tap/configuration-test.js b/test/tap/configuration-test.js index feac5c1..2eef979 100644 --- a/test/tap/configuration-test.js +++ b/test/tap/configuration-test.js @@ -3,54 +3,79 @@ const test = require('tap').test; const sandbox = require('@log4js-node/sandboxed-module'); -test('log4js configure', (batch) => { - batch.test('when configuration file loaded via LOG4JS_CONFIG env variable', (t) => { - process.env.LOG4JS_CONFIG = 'some/path/to/mylog4js.json'; - let fileRead = 0; - const modulePath = 'some/path/to/mylog4js.json'; - const pathsChecked = []; - const mtime = new Date(); +const modulePath = 'some/path/to/mylog4js.json'; +const pathsChecked = []; - const fakeFS = { +let fakeFS = {}; +let dependencies; +let fileRead; + +test('log4js configure', (batch) => { + batch.beforeEach((done) => { + fileRead = 0; + + fakeFS = { config: { appenders: { - console: { type: 'console', layout: { type: 'messagePassThrough' } } + console: { + type: 'console', + layout: { type: 'messagePassThrough' } + } }, - categories: { default: { appenders: ['console'], level: 'INFO' } } + categories: { + default: { + appenders: ['console'], + level: 'INFO' + } + } }, - readdirSync: function (dir) { - return require('fs').readdirSync(dir); - }, - readFileSync: function (file, encoding) { + readdirSync: dir => require('fs').readdirSync(dir), + readFileSync: (file, encoding) => { fileRead += 1; - t.type(file, 'string'); - t.equal(file, modulePath); - t.equal(encoding, 'utf8'); + batch.type(file, 'string'); + batch.equal(file, modulePath); + batch.equal(encoding, 'utf8'); return JSON.stringify(fakeFS.config); }, - statSync: function (path) { + statSync: (path) => { pathsChecked.push(path); if (path === modulePath) { - return { mtime: mtime }; + return { mtime: new Date() }; } throw new Error('no such file'); } }; - const log4js = sandbox.require( - '../../lib/log4js', - { - requires: { - fs: fakeFS, - } + dependencies = { + requires: { + fs: fakeFS } - ); + }; + + done(); + }); + + batch.test('when configuration file loaded via LOG4JS_CONFIG env variable', (t) => { + process.env.LOG4JS_CONFIG = 'some/path/to/mylog4js.json'; + + const log4js = sandbox.require('../../lib/log4js', dependencies); log4js.getLogger('test-logger'); + t.equal(fileRead, 1, 'should load the specified local config file'); delete process.env.LOG4JS_CONFIG; - t.equal(fileRead, 1, 'should load the specified local config file'); + t.end(); + }); + + batch.test('when configuration is set via configure() method call, return the log4js object', (t) => { + const log4js = sandbox.require('../../lib/log4js', dependencies).configure(fakeFS.config); + t.type(log4js, 'object', 'Configure method call should return the log4js object!'); + + const log = log4js.getLogger('daemon'); + t.type(log, 'object', 'log4js object, returned by configure(...) method should be able to create log object.'); + t.type(log.info, 'function'); + t.end(); }); diff --git a/test/tap/redisAppender-test.js b/test/tap/redisAppender-test.js index 25e05e8..d93fd69 100644 --- a/test/tap/redisAppender-test.js +++ b/test/tap/redisAppender-test.js @@ -18,7 +18,10 @@ function setupLogging(category, options) { publish: function (channel, message, callback) { fakeRedis.msgs.push({ channel: channel, message: message }); fakeRedis.publishCb = callback; - } + }, + quit: function () { + fakeRedis.quitCalled = true; + }, }; } }; @@ -46,6 +49,7 @@ function setupLogging(category, options) { return { logger: log4js.getLogger(category), + log4js: log4js, fakeRedis: fakeRedis, fakeConsole: fakeConsole }; @@ -129,5 +133,14 @@ test('log4js redisAppender', (batch) => { t.end(); }); + batch.test('shutdown', (t) => { + const setup = setupLogging('shutdown', { type: 'redis', channel: 'testing' }); + + setup.log4js.shutdown(() => { + t.ok(setup.fakeRedis.quitCalled); + t.end(); + }); + }); + batch.end(); }); diff --git a/types/log4js.d.ts b/types/log4js.d.ts index 01c48eb..e0ad4fb 100644 --- a/types/log4js.d.ts +++ b/types/log4js.d.ts @@ -1,9 +1,18 @@ // Type definitions for log4js +export interface Log4js { + getLogger, + configure, + addLayout, + connectLogger, + levels, + shutdown +} + export function getLogger(category?: string): Logger; -export function configure(filename: string): void; -export function configure(config: Configuration): void; +export function configure(filename: string): Log4js; +export function configure(config: Configuration): Log4js; export function addLayout(name: string, config: (a: any) => (logEvent: LoggingEvent) => string): void; diff --git a/types/test.ts b/types/test.ts index 91e1b84..ffd8bf3 100644 --- a/types/test.ts +++ b/types/test.ts @@ -108,3 +108,8 @@ configure({ appenders: { cheese: { type: 'file', filename: 'cheese.log' } }, categories: { default: { appenders: ['cheese'], level: 'error' } } }); + +log4js.configure('./filename').getLogger(); +const logger7 = log4js.getLogger(); +logger7.level = 'debug'; +logger7.debug("Some debug messages");