UNPKG

yapm

Version:

package manager for io.js (npm fork)

161 lines (134 loc) 3.95 kB
var EE = require('events').EventEmitter var log = exports = module.exports = new EE var util = require('util') var fmt = require('printf'); var colors = { silly: 90, verbose: 90, info: 36, http: 32, warn: 33, error: 31 } log.stream = log.cursor = process.stderr // by default, let ansi decide based on tty-ness. var colorEnabled = undefined log.enableColor = function () { colorEnabled = true this.cursor.enabled = true } log.disableColor = function () { colorEnabled = false this.cursor.enabled = false } // default level log.level = 'info' // temporarily stop emitting, but don't drop log.pause = function () { this._paused = true } log.resume = function () { if (!this._paused) return this._paused = false var b = this._buffer this._buffer = [] b.forEach(function (m) { this.emitLog(m) }, this) } log._buffer = [] var id = 0 log.record = [] log.maxRecordSize = 10000 log.log = function (lvl, prefix, message) { var l = this.levels[lvl] if (l === undefined) { return this.emit('error', new Error(util.format( 'Undefined log level: %j', lvl))) } var a = new Array(arguments.length - 2) var stack = null for (var i = 2; i < arguments.length; i ++) { var arg = a[i-2] = arguments[i] // resolve stack traces to a plain string. if (typeof arg === 'object' && arg && (arg instanceof Error) && arg.stack) { arg.stack = stack = arg.stack + '' } } if (stack) a.unshift(stack + '\n') message = util.format.apply(util, a) var m = { id: id++, level: lvl, prefix: String(prefix || ''), message: message, messageRaw: a } this.emit('log', m) this.emit('log.' + lvl, m) if (m.prefix) this.emit(m.prefix, m) this.record.push(m) var mrs = this.maxRecordSize var n = this.record.length - mrs if (n > mrs / 10) { var newSize = Math.floor(mrs * 0.9) this.record = this.record.slice(-1 * newSize) } this.emitLog(m) }.bind(log) log.emitLog = function (m) { if (this._paused) { this._buffer.push(m) return } var l = this.levels[m.level] if (l === undefined) return if (l < this.levels[this.level]) return if (l > 0 && !isFinite(l)) return var style = log.style[m.level] var disp = log.disp[m.level] || m.level var msg = m.message; // indent if (~msg.indexOf('\n')) { msg = msg.replace(/^/gm, Array(11 + (m.prefix.length ? m.prefix.length : -1)).join(' ')).trim(); } // color var c = colors[m.level] || 0; // put some spacing between prefix and msg, // but only if prefix exists if (m.prefix) msg = ' ' + msg; // format // shorten 'verbose' to 'verb', because it's too long var level = m.level === 'verbose' ? 'verb' : m.level if (colorEnabled === true || (colorEnabled === undefined && process.stderr.isTTY)) { msg = fmt(' \033[' + c + 'm%5s\033[0m \033[90m-\033[0m \033[35m%s\033[0m%s\n', level, m.prefix, msg); } else { msg = fmt(' %5s - %s%s\n', level, m.prefix, msg); } process.stderr.write(msg); } log.addLevel = function (lvl, n, style, disp) { if (!disp) disp = lvl this.levels[lvl] = n this.style[lvl] = style if (!this[lvl]) this[lvl] = function () { var a = new Array(arguments.length + 1) a[0] = lvl for (var i = 0; i < arguments.length; i ++) { a[i + 1] = arguments[i] } return this.log.apply(this, a) }.bind(this) this.disp[lvl] = disp } log.prefixStyle = { fg: 'magenta' } log.headingStyle = { fg: 'white', bg: 'black' } log.style = {} log.levels = {} log.disp = {} log.addLevel('silly', -Infinity, { inverse: true }, 'sill') log.addLevel('verbose', 1000, { fg: 'blue', bg: 'black' }, 'verb') log.addLevel('info', 2000, { fg: 'green' }) log.addLevel('http', 3000, { fg: 'green', bg: 'black' }) log.addLevel('warn', 4000, { fg: 'black', bg: 'yellow' }, 'WARN') log.addLevel('error', 5000, { fg: 'red', bg: 'black' }, 'ERR!') log.addLevel('silent', Infinity)