Files
elasticsearch-js/src/lib/logger.js

158 lines
4.0 KiB
JavaScript

var Log = require('./log'),
_ = require('./utils');
/**
* Abstract class providing common functionality to loggers
* @param {[type]} config [description]
* @param {[type]} bridge [description]
*/
function LoggerAbstract(config, bridge) {
this.bridge = bridge;
this.listeningLevels = [];
// bound copies of the event handlers
this.handlers = _.reduce(Log.levels, function (handlers, name) {
handlers[name] = _.bindKey(this, 'on' + _.studlyCase(name));
return handlers;
}, {}, this);
// then the bridge closes, remove our event listeners
this.bridge.on('closing', _.bindKey(this, 'cleanUpListeners'));
this.setupListeners(config.levels);
}
function padNumToTen(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
/**
* Create a timestamp string used in the format function. Defers to Log.timestamp if it is defined,
* Also, feel free to override this at the logger level.
* @return {String} - Timestamp in ISO 8601 UTC
*/
LoggerAbstract.prototype.timestamp = function () {
var d = new Date();
return d.getUTCFullYear() + '-' +
padNumToTen(d.getUTCMonth() + 1) + '-' +
padNumToTen(d.getUTCDate()) + 'T' +
padNumToTen(d.getUTCHours()) + ':' +
padNumToTen(d.getUTCMinutes()) + ':' +
padNumToTen(d.getUTCSeconds()) + 'Z';
};
function indent(text, spaces) {
var space = _.repeat(' ', spaces || 2);
return text.split(/\r?\n/).map(function (line) {
return space + line;
}).join('\n');
}
LoggerAbstract.prototype.format = function (label, message) {
return label + ': ' + this.timestamp() + '\n' + indent(message) + '\n\n';
};
LoggerAbstract.prototype.write = function () {
throw new Error('This should be overwritten by the logger');
};
/**
* Clear the current event listeners and then re-listen for events based on the level specified
*
* @method setupListeners
* @private
* @param {Integer} level - The max log level that this logger should listen to
* @return {undefined}
*/
LoggerAbstract.prototype.setupListeners = function (levels) {
this.cleanUpListeners();
this.listeningLevels = levels;
_.each(this.listeningLevels, function (level) {
this.bridge.on(level, this.handlers[level]);
}, this);
};
/**
* Clear the current event listeners
*
* @method cleanUpListeners
* @private
* @return {undefined}
*/
LoggerAbstract.prototype.cleanUpListeners = function () {
_.each(this.listeningLevels, function (level) {
this.bridge.removeListener(level, this.handlers[level]);
}, this);
};
/**
* Handler for the bridges "error" event
*
* @method onError
* @private
* @param {Error} e - The Error object to log
* @return {undefined}
*/
LoggerAbstract.prototype.onError = function (e) {
this.write((e.name === 'Error' ? 'ERROR' : e.name), e.stack);
};
/**
* Handler for the bridges "warning" event
*
* @method onWarning
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onWarning = function (msg) {
this.write('WARNING', msg);
};
/**
* Handler for the bridges "info" event
*
* @method onInfo
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onInfo = function (msg) {
this.write('INFO', msg);
};
/**
* Handler for the bridges "debug" event
*
* @method onDebug
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onDebug = function (msg) {
this.write('DEBUG', msg);
};
/**
* Handler for the bridges "trace" event
*
* @method onTrace
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onTrace = function (method, url, body, responseBody, responseStatus) {
var message = 'curl "' + url.replace(/"/g, '\\"') + '" -X' + method.toUpperCase();
if (body) {
message += ' -d "' + body.replace(/"/g, '\\"') + '"';
}
message += '\n<- ' + responseStatus + '\n' + responseBody;
this.write('TRACE', message);
};
module.exports = LoggerAbstract;