diff --git a/lib/logger.js b/lib/logger.js index 02047b1..94d6828 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -156,7 +156,7 @@ function Logger(key, options) { loggers.push(this); } -Logger.prototype.log = function(statement, opts) { +Logger.prototype.log = function(statement, opts, callback) { this._err = false; if (typeof statement === 'object') { statement = JSON.parse(JSON.stringify(statement)); @@ -173,7 +173,9 @@ Logger.prototype.log = function(statement, opts) { }; if (opts) { - if (typeof opts === 'string') { + if (typeof opts === 'function') { + callback = opts; + } else if (typeof opts === 'string') { if (opts.length > configs.MAX_INPUT_LENGTH) { debug('Level had more than ' + configs.MAX_INPUT_LENGTH + ' chars, was truncated'); opts = opts.substring(0, configs.MAX_INPUT_LENGTH); @@ -226,15 +228,19 @@ Logger.prototype.log = function(statement, opts) { return this._err; } - this._bufferLog(message); + this._bufferLog(message, callback); }; -Logger.prototype._bufferLog = function(message) { +Logger.prototype._bufferLog = function(message, callback) { if (!message || !message.line) { debug('Ignoring empty message'); return; } + if (!callback || typeof callback !== 'function') { + callback = (err) => { debug(err); }; + } + if (this._max_length && message.line.length > configs.MAX_LINE_LENGTH) { message.line = message.line.substring(0, configs.MAX_LINE_LENGTH) + ' (cut off, too long...)'; debug('Line was longer than ' + configs.MAX_LINE_LENGTH + ' chars and was truncated.'); @@ -263,14 +269,14 @@ Logger.prototype._bufferLog = function(message) { debug('Backing off.'); this._isLoggingBackedOff = false; this._flusher = setTimeout(() => { - this._flush((err) => { debug(err); }); + this._flush(callback); }, this._retryTimeout); } if (!this._flusher) { debug('No scheduled flush. Scheduling for %d ms from now.', configs.FLUSH_INTERVAL); this._flusher = setTimeout(() => { - this._flush((err) => { debug(err); }); + this._flush(callback); }, this._flushInterval); } }; @@ -358,11 +364,16 @@ Logger.prototype._flush = function(callback) { * Populate short-hand for each supported Log Level */ configs.LOG_LEVELS.forEach(function(level) { - var l = level.toLowerCase(); - Logger.prototype[l] = function(statement, opts) { + const levelFunctionName = level.toLowerCase(); + Logger.prototype[levelFunctionName] = function(statement, opts, callback) { + if (opts && typeof opts === 'function') { + callback = opts; + opts = {}; + } opts = opts || {}; opts.level = level; - this.log(statement, opts); + + this.log(statement, opts, callback); }; }); diff --git a/test/logger.js b/test/logger.js index b4fdca0..ff65ed7 100644 --- a/test/logger.js +++ b/test/logger.js @@ -31,6 +31,9 @@ describe('Test all Levels', function() { let allLevelsServer; let sentLines = []; let sentLevels = []; + + let callbackResult; + const testCallback = (er, res) => { callbackResult = res; }; beforeEach(function(done) { allLevelsServer = http.createServer(function(req, res) { req.on('data', function(data) { @@ -58,6 +61,45 @@ describe('Test all Levels', function() { sentLines = []; sentLevels = []; body = ''; + callbackResult = ''; + }); + describe('passing callback', function() { + it('Executes callback when provided - debug', function(done) { + allLevelsLogger.debug('Sent a log', testCallback); + setTimeout(function() { + assert(callbackResult.httpStatus === 200); + assert(sentLines[0] === 'Sent a log'); + assert(sentLevels[0] === 'DEBUG'); + done(); + }, configs.FLUSH_INTERVAL + 200); + }); + it('Executes callback when provided - trace', function(done) { + allLevelsLogger.trace('Sent a log1', testCallback); + setTimeout(function() { + assert(callbackResult.httpStatus === 200); + assert(sentLines[0] === 'Sent a log1'); + assert(sentLevels[0] === 'TRACE'); + done(); + }, configs.FLUSH_INTERVAL + 200); + }); + it('Executes callback when provided - info', function(done) { + allLevelsLogger.info('Sent a log2', testCallback); + setTimeout(function() { + assert(callbackResult.httpStatus === 200); + assert(sentLines[0] === 'Sent a log2'); + assert(sentLevels[0] === 'INFO'); + done(); + }, configs.FLUSH_INTERVAL + 200); + }); + it('Executes callback when provided - warn', function(done) { + allLevelsLogger.warn('Sent a log3', testCallback); + setTimeout(function() { + assert(callbackResult.httpStatus === 200); + assert(sentLines[0] === 'Sent a log3'); + assert(sentLevels[0] === 'WARN'); + done(); + }, configs.FLUSH_INTERVAL + 200); + }); }); it('Debug Function', function(done) { allLevelsLogger.debug('Sent a log'); @@ -107,6 +149,7 @@ describe('Test all Levels', function() { done(); }, configs.FLUSH_INTERVAL + 200); }); + }); describe('Testing for Correctness', function() { @@ -599,4 +642,15 @@ describe('HTTP Exception Handling', function() { done(); }, configs.FLUSH_INTERVAL + 200); }); + it('if log has a callback, it should be called with an error', function(done) { + const opts = testHelper.createOptions({port: port}); + const flushAllTest = Logger.createLogger(testHelper.apikey, opts); + let callbackError; + flushAllTest.log('Test line', (e) => {callbackError = e;}); + + setTimeout(function() { + assert(callbackError === 'An error occured while making the request. Response status code: 302 Found'); + done(); + }, configs.FLUSH_INTERVAL + 200); + }); });