Files
elasticsearch-js/src/lib/logger.js
2017-06-14 18:48:24 -07:00

181 lines
4.4 KiB
JavaScript

const _ = require('./utils');
/**
* Abstract class providing common functionality to loggers
* @param {[type]} log [description]
* @param {[type]} config [description]
*/
function LoggerAbstract(log, config) {
this.log = log;
this.listeningLevels = [];
_.makeBoundMethods(this);
// when the log closes, remove our event listeners
this.log.once('closing', this.bound.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 () {
const 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) {
const 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 = [];
_.each(levels, _.bind(function (level) {
const fnName = 'on' + _.ucfirst(level);
if (this.bound[fnName]) {
this.listeningLevels.push(level);
this.log.on(level, this.bound[fnName]);
} else {
throw new Error('Unable to listen for level "' + level + '"');
}
}, this));
};
/**
* Clear the current event listeners
*
* @method cleanUpListeners
* @private
* @return {undefined}
*/
LoggerAbstract.prototype.cleanUpListeners = _.handler(function () {
_.each(this.listeningLevels, _.bind(function (level) {
this.log.removeListener(level, this.bound['on' + _.ucfirst(level)]);
}, this));
});
/**
* Handler for the logs "error" event
*
* @method onError
* @private
* @param {Error} e - The Error object to log
* @return {undefined}
*/
LoggerAbstract.prototype.onError = _.handler(function (e) {
this.write((e.name === 'Error' ? 'ERROR' : e.name), e.stack);
});
/**
* Handler for the logs "warning" event
*
* @method onWarning
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onWarning = _.handler(function (msg) {
this.write('WARNING', msg);
});
/**
* Handler for the logs "info" event
*
* @method onInfo
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onInfo = _.handler(function (msg) {
this.write('INFO', msg);
});
/**
* Handler for the logs "debug" event
*
* @method onDebug
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onDebug = _.handler(function (msg) {
this.write('DEBUG', msg);
});
/**
* Handler for the logs "trace" event
*
* @method onTrace
* @private
* @param {String} msg - The message to be logged
* @return {undefined}
*/
LoggerAbstract.prototype.onTrace = _.handler(function (requestDetails) {
this.write('TRACE', this._formatTraceMessage(requestDetails));
});
LoggerAbstract.prototype._formatTraceMessage = function (req) {
return '-> ' + req.method + ' ' + req.url + '\n' +
this._prettyJson(req.body) + '\n' +
'<- ' + req.status + '\n' +
this._prettyJson(req.response);
/*
-> GET https://sldfkjsdlfksjdf:9200/slsdkfjlxckvxhclks?sdlkj=sdlfkje
{
asdflksjdf
}
<- 502
{
sldfksjdlf
}
*/
};
LoggerAbstract.prototype._prettyJson = function (body) {
try {
if (typeof body === 'string') {
body = JSON.parse(body);
}
return JSON.stringify(body, null, ' ').replace(/'/g, '\\u0027');
} catch (e) {
return typeof body === 'string' ? body : '';
}
};
module.exports = LoggerAbstract;