UNPKG

prepper

Version:

Prepper is an event based api for pre-processing log events before routing them to your logging framework of choice

113 lines (98 loc) 4.82 kB
var EventEmitter = require('events').EventEmitter var util = require('util') var R = require('ramda') var isString = R.compose(R.equals('String'), R.type) var isObject = R.compose(R.equals('Object'), R.type) var isError = (o) => o instanceof Error var merge = require('lodash.merge') var Sequence = require('./handlers/Sequence') function Logger(_options) { var levels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] var handlers = _options && _options.handlers var sequence = _options && _options.sequence || new Sequence(handlers) var options = merge({}, { message: '', level: 'info', maxListeners: 100, sequence: sequence }, _options) var self = this self.child = function(_options) { var sequence = _options.sequence ? _options.sequence : new Sequence(_options.handlers) var child = new Logger(merge({}, { sequence: sequence }, _options)) child.on('message', self.log) return child } self.log = function log(arg1, arg2, arg3) { self._logEvent.apply(self, toArray(arguments)) return self } levels.forEach(function(level) { self[level] = function(arg1, arg2, arg3) { self._logEvent.apply(self, toArray(arguments).concat(level)) return self } }) self._logEvent = function(arg1, arg2, arg3, arg4) { // message, error, context, level if (arguments.length === 4) return self.emit('internal-message', merge( {}, { message: options.message, level: options.level }, arg3, toError(arg2), toMessage(arg1), toLevel(arg1, arg2, arg3, arg4) )) // message, error, level if (arguments.length === 3 && isString(arg1) && isError(arg2) && isString(arg3)) return self._logEvent(arg1, arg2, null, arg3) // message, error, context if (arguments.length === 3 && isString(arg1) && isError(arg2) && isObject(arg3)) return self._logEvent(arg1, arg2, arg3, null) // message, context, level if (arguments.length === 3 && isString(arg1) && isObject(arg2) && isString(arg3)) return self._logEvent(arg1, null, arg2, arg3) // error, context, level if (arguments.length === 3 && isError(arg1) && isObject(arg2) && isString(arg3)) return self._logEvent(null, arg1, arg2, arg3) // message, level if (arguments.length === 2 && isString(arg1) && isString(arg2)) return self._logEvent(arg1, null, null, arg2) // message, error if (arguments.length === 2 && isString(arg1) && isError(arg2)) return self._logEvent(arg1, arg2, null, null) // message, context if (arguments.length === 2 && isString(arg1) && isObject(arg2)) return self._logEvent(arg1, null, arg2, null) // error, level if (arguments.length === 2 && isError(arg1) && isString(arg2)) return self._logEvent(null, arg1, null, arg2) // error, context if (arguments.length === 2 && isError(arg1) && isObject(arg2)) return self._logEvent(null, arg1, arg2, null) // context, level if (arguments.length === 2 && isObject(arg1) && isString(arg2)) return self._logEvent(null, null, arg1, arg2) // message if (arguments.length === 1 && isString(arg1)) return self._logEvent(arg1, null, null, null) // error if (arguments.length === 1 && isError(arg1)) return self._logEvent(null, arg1, null, null) // context if (arguments.length === 1 && isObject(arg1)) return self._logEvent(null, null, arg1, null) // usage error return self._logEvent(null, toError(new Error('Logger usage error')), { arguments: toArray(arguments) }, 'error') } function toMessage(message) { return message ? { message: message } : {} } function toError(error) { return error ? { message: error.message && error.message !== 'null' ? error.message : 'An unspecified error occurred', level: error.level || 'error', error: R.pipe(R.pick(Object.getOwnPropertyNames(error)), R.omit('level'))(error) } : {} } function toLevel(message, error, context, level) { if (level) return { level: level } if (error && error.level) return { level: error.level } if (context && context.level) return { level: context.level } if (error) return { level: 'error' } return {} } function toArray(args) { return Array.prototype.slice.call(args) } EventEmitter.call(self); self.setMaxListeners(options.maxListeners) self.on('internal-message', options.sequence.handle) options.sequence.on('message', function(event) { self.emit('message', event) }) } util.inherits(Logger, EventEmitter) module.exports = Logger