diff --git a/lib/appenders/redis.js b/lib/appenders/redis.js index 33a8d66..66036ef 100644 --- a/lib/appenders/redis.js +++ b/lib/appenders/redis.js @@ -1,29 +1,32 @@ 'use strict'; -const layouts = require('../layouts'); const redis = require('redis'); const util = require('util'); function redisAppender(config, layout) { - layout = layout || layouts.messagePassThroughLayout; - const redisClient = redis.createClient(config.port, config.host, { auth_pass: config.pass }); + const host = config.host || '127.0.0.1'; + const port = config.port || 6379; + const auth = config.pass ? { auth_pass: config.pass } : {}; + const redisClient = redis.createClient(port, host, auth); + redisClient.on('error', (err) => { if (err) { - console.error('log4js.redisAppender - %s:%p Error: %s', config.host, config.port, util.inspect(err)); + console.error(`log4js.redisAppender - ${host}:${port} Error: ${util.inspect(err)}`); } }); + return function (loggingEvent) { const message = layout(loggingEvent); redisClient.publish(config.channel, message, (err) => { if (err) { - console.error('log4js.redisAppender - %s:%p Error: %s', config.host, config.port, util.inspect(err)); + console.error(`log4js.redisAppender - ${host}:${port} Error: ${util.inspect(err)}`); } }); }; } -function configure(config) { - let layout; +function configure(config, layouts) { + let layout = layouts.messagePassThroughLayout; if (config.layout) { layout = layouts.layout(config.layout.type, config.layout); } @@ -31,5 +34,4 @@ function configure(config) { return redisAppender(config, layout); } -module.exports.appender = redisAppender; module.exports.configure = configure; diff --git a/test/tap/redisAppender-test.js b/test/tap/redisAppender-test.js index 788a613..7f67d7a 100644 --- a/test/tap/redisAppender-test.js +++ b/test/tap/redisAppender-test.js @@ -1,184 +1,127 @@ 'use strict'; const test = require('tap').test; -const log4js = require('../../lib/log4js'); +// const log4js = require('../../lib/log4js'); const sandbox = require('sandboxed-module'); function setupLogging(category, options) { - const msgs = []; - - const redisCredentials = { - type: options.type, - host: options.host, - port: options.port, - pass: options.pass, - channel: options.channel, - layout: options.layout - }; - const fakeRedis = { + msgs: [], createClient: function (port, host, optionR) { this.port = port; this.host = host; - this.optionR = {}; - this.optionR.auth_pass = optionR.pass; + this.optionR = optionR; return { on: function (event, callback) { - callback('throw redis error #1'); + fakeRedis.errorCb = callback; }, publish: function (channel, message, callback) { - msgs.push(message); - callback(null, {status: 'sent'}); + fakeRedis.msgs.push({ channel: channel, message: message }); + fakeRedis.publishCb = callback; } }; } }; - const fakeLayouts = { - layout: function (type, config) { - this.type = type; - this.config = config; - return log4js.layouts.messagePassThroughLayout; - }, - basicLayout: log4js.layouts.basicLayout, - coloredLayout: log4js.layouts.coloredLayout, - messagePassThroughLayout: log4js.layouts.messagePassThroughLayout - }; - - const fakeUtil = { - inspect: function (item) { - return JSON.stringify(item); - } - }; - const fakeConsole = { errors: [], - logs: [], - error: function (msg, value) { - this.errors.push({ msg: msg, value: value }); - }, - log: function (msg, value) { - this.logs.push({ msg: msg, value: value }); + error: function (msg) { + this.errors.push(msg); } }; - const redisModule = sandbox.require('../../lib/appenders/redis', { + const log4js = sandbox.require('../../lib/log4js', { requires: { - 'redis': fakeRedis, - '../layouts': fakeLayouts, - 'util': fakeUtil + redis: fakeRedis }, globals: { console: fakeConsole } }); - - log4js.addAppender(redisModule.configure(options), category); + log4js.configure({ + appenders: { redis: options }, + categories: { default: { appenders: ['redis'], level: 'trace' } } + }); return { logger: log4js.getLogger(category), - redis: fakeRedis, - layouts: fakeLayouts, - console: fakeConsole, - messages: msgs, - credentials: redisCredentials + fakeRedis: fakeRedis, + fakeConsole: fakeConsole }; } -function checkMessages(assert, result) { - for (let i = 0; i < result.messages.length; i++) { - assert.ok(new RegExp(`Log event #${i + 1}`).test(result.messages[i])); - } -} - -log4js.clearAppenders(); - test('log4js redisAppender', (batch) => { batch.test('redis setup', (t) => { const result = setupLogging('redis setup', { - host: '127.0.0.1', - port: 6739, + host: '123.123.123.123', + port: 1234, pass: '123456', channel: 'log', type: 'redis', layout: { type: 'pattern', - pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m' + pattern: 'cheese %m' } }); + + result.logger.info('Log event #1'); + result.fakeRedis.publishCb(); + t.test('redis credentials should match', (assert) => { - assert.equal(result.credentials.host, '127.0.0.1'); - assert.equal(result.credentials.port, 6739); - assert.equal(result.credentials.pass, '123456'); - assert.equal(result.credentials.channel, 'log'); - assert.equal(result.credentials.type, 'redis'); - assert.equal(result.credentials.layout.type, 'pattern'); - assert.equal(result.credentials.layout.pattern, '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m'); + assert.equal(result.fakeRedis.host, '123.123.123.123'); + assert.equal(result.fakeRedis.port, 1234); + assert.equal(result.fakeRedis.optionR.auth_pass, '123456'); + assert.equal(result.fakeRedis.msgs.length, 1, 'should be one message only'); + assert.equal(result.fakeRedis.msgs[0].channel, 'log'); + assert.equal(result.fakeRedis.msgs[0].message, 'cheese Log event #1'); assert.end(); }); t.end(); }); - batch.test('basic usage', (t) => { - const setup = setupLogging('basic usage', { - host: '127.0.0.1', - port: 6739, - pass: '', - channel: 'log', + batch.test('default values', (t) => { + const setup = setupLogging('defaults', { type: 'redis', - layout: { - type: 'pattern', - pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m' - } + channel: 'thing' }); - setup.logger.info('Log event #1'); + setup.logger.info('just testing'); + setup.fakeRedis.publishCb(); + + t.test('should use localhost', (assert) => { + assert.equal(setup.fakeRedis.host, '127.0.0.1'); + assert.equal(setup.fakeRedis.port, 6379); + assert.same(setup.fakeRedis.optionR, {}); + assert.end(); + }); + + t.test('should use message pass through layout', (assert) => { + assert.equal(setup.fakeRedis.msgs.length, 1); + assert.equal(setup.fakeRedis.msgs[0].channel, 'thing'); + assert.equal(setup.fakeRedis.msgs[0].message, 'just testing'); + assert.end(); + }); - t.equal(setup.messages.length, 1, 'should be one message only'); - checkMessages(t, setup); t.end(); }); + batch.test('redis errors', (t) => { + const setup = setupLogging('errors', { type: 'redis', channel: 'testing' }); - batch.test('config with layout', (t) => { - const result = setupLogging('config with layout', { - layout: { - type: 'redis' - } + setup.fakeRedis.errorCb('oh no, error on connect'); + setup.logger.info('something something'); + setup.fakeRedis.publishCb('oh no, error on publish'); + + t.test('should go to the console', (assert) => { + assert.equal(setup.fakeConsole.errors.length, 2); + assert.equal(setup.fakeConsole.errors[0], 'log4js.redisAppender - 127.0.0.1:6379 Error: \'oh no, error on connect\''); + assert.equal(setup.fakeConsole.errors[1], 'log4js.redisAppender - 127.0.0.1:6379 Error: \'oh no, error on publish\''); + assert.end(); }); - t.equal(result.layouts.type, 'redis', 'should configure layout'); t.end(); }); - batch.test('separate notification for each event', (t) => { - const setup = setupLogging('separate notification for each event', { - host: '127.0.0.1', - port: 6739, - pass: '', - channel: 'log', - type: 'redis', - layout: { - type: 'pattern', - pattern: '%d{yyyy-MM-dd hh:mm:ss:SSS}#%p#%m' - } - }); - setTimeout(() => { - setup.logger.info('Log event #1'); - }, 0); - setTimeout(() => { - setup.logger.info('Log event #2'); - }, 500); - setTimeout(() => { - setup.logger.info('Log event #3'); - }, 1100); - setTimeout(() => { - t.equal(setup.messages.length, 3, 'should be three messages'); - checkMessages(t, setup); - t.end(); - }, 3000); - }); - batch.end(); });