You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
4.9 KiB
269 lines
4.9 KiB
/** |
|
* tFunk for colours/compiler |
|
*/ |
|
var tfunk = require("tfunk"); |
|
|
|
/** |
|
* Lodash clonedeep & merge |
|
*/ |
|
var _ = require("./lodash.custom"); |
|
|
|
/** |
|
* Default configuration. |
|
* Can be overridden in first constructor arg |
|
*/ |
|
var defaults = { |
|
|
|
/** |
|
* Initial log level |
|
*/ |
|
level: "info", |
|
|
|
/** |
|
* Prefix for logger |
|
*/ |
|
prefix: "", |
|
|
|
/** |
|
* Available levels and their score |
|
*/ |
|
levels: { |
|
"trace": 100, |
|
"debug": 200, |
|
"warn": 300, |
|
"info": 400, |
|
"error": 500 |
|
}, |
|
|
|
/** |
|
* Default prefixes |
|
*/ |
|
prefixes: { |
|
"trace": "[trace] ", |
|
"debug": "{yellow:[debug]} ", |
|
"info": "{cyan:[info]} ", |
|
"warn": "{magenta:[warn]} ", |
|
"error": "{red:[error]} " |
|
}, |
|
|
|
/** |
|
* Should easy log statement be prefixed with the level? |
|
*/ |
|
useLevelPrefixes: false |
|
}; |
|
|
|
|
|
/** |
|
* @param {Object} config |
|
* @constructor |
|
*/ |
|
var Logger = function(config) { |
|
|
|
if (!(this instanceof Logger)) { |
|
return new Logger(config); |
|
} |
|
|
|
config = config || {}; |
|
|
|
this._mute = false; |
|
this.config = _.merge({}, defaults, config); |
|
this.addLevelMethods(this.config.levels); |
|
this.compiler = new tfunk.Compiler(this.config.custom || {}, this.config); |
|
this._memo = {}; |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Set an option once |
|
* @param path |
|
* @param value |
|
*/ |
|
Logger.prototype.setOnce = function (path, value) { |
|
|
|
if (typeof this.config[path] !== "undefined") { |
|
|
|
if (typeof this._memo[path] === "undefined") { |
|
this._memo[path] = this.config[path]; |
|
} |
|
|
|
this.config[path] = value; |
|
} |
|
|
|
return this; |
|
}; |
|
/** |
|
* Add convenience method such as |
|
* logger.warn("msg") |
|
* logger.error("msg") |
|
* logger.info("msg") |
|
* |
|
* instead of |
|
* logger.log("warn", "msg"); |
|
* @param items |
|
*/ |
|
Logger.prototype.addLevelMethods = function (items) { |
|
Object.keys(items).forEach(function (item) { |
|
if (!this[item]) { |
|
this[item] = function () { |
|
var args = Array.prototype.slice.call(arguments); |
|
this.log.apply(this, args); |
|
return this; |
|
}.bind(this, item); |
|
} |
|
}, this); |
|
}; |
|
/** |
|
* Reset the state of the logger. |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.reset = function () { |
|
|
|
this.setLevel(defaults.level) |
|
.setLevelPrefixes(defaults.useLevelPrefixes) |
|
.mute(false); |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* @param {String} level |
|
* @returns {boolean} |
|
*/ |
|
Logger.prototype.canLog = function (level) { |
|
return this.config.levels[level] >= this.config.levels[this.config.level] && !this._mute; |
|
}; |
|
|
|
/** |
|
* Log to the console with prefix |
|
* @param {String} level |
|
* @param {String} msg |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.log = function (level, msg) { |
|
|
|
var args = Array.prototype.slice.call(arguments); |
|
|
|
this.logOne(args, msg, level); |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Set the log level |
|
* @param {String} level |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.setLevel = function (level) { |
|
|
|
this.config.level = level; |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* @param {boolean} state |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.setLevelPrefixes = function (state) { |
|
|
|
this.config.useLevelPrefixes = state; |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* @param prefix |
|
*/ |
|
Logger.prototype.setPrefix = function (prefix) { |
|
if (typeof prefix === "string") { |
|
this.compiler.prefix = this.compiler.compile(prefix, true); |
|
} |
|
if (typeof prefix === "function") { |
|
this.compiler.prefix = prefix; |
|
} |
|
}; |
|
|
|
/** |
|
* @param {String} level |
|
* @param {String} msg |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.unprefixed = function (level, msg) { |
|
|
|
var args = Array.prototype.slice.call(arguments); |
|
|
|
this.logOne(args, msg, level, true); |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* @param {Array} args |
|
* @param {String} msg |
|
* @param {String} level |
|
* @param {boolean} [unprefixed] |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.logOne = function (args, msg, level, unprefixed) { |
|
|
|
if (!this.canLog(level)) { |
|
return; |
|
} |
|
|
|
args = args.slice(2); |
|
|
|
if (this.config.useLevelPrefixes && !unprefixed) { |
|
msg = this.config.prefixes[level] + msg; |
|
} |
|
|
|
msg = this.compiler.compile(msg, unprefixed); |
|
|
|
args.unshift(msg); |
|
|
|
console.log.apply(console, args); |
|
|
|
this.resetTemps(); |
|
|
|
return this; |
|
}; |
|
|
|
/** |
|
* Reset any temporary value |
|
*/ |
|
Logger.prototype.resetTemps = function () { |
|
|
|
Object.keys(this._memo).forEach(function (key) { |
|
this.config[key] = this._memo[key]; |
|
}, this); |
|
}; |
|
|
|
/** |
|
* Mute the logger |
|
*/ |
|
Logger.prototype.mute = function (bool) { |
|
|
|
this._mute = bool; |
|
return this; |
|
}; |
|
|
|
/** |
|
* Clone the instance to share setup |
|
* @param opts |
|
* @returns {Logger} |
|
*/ |
|
Logger.prototype.clone = function (opts) { |
|
|
|
var config = _.cloneDeep(this.config); |
|
|
|
if (typeof opts === "function") { |
|
config = opts(config) || {}; |
|
} else { |
|
config = _.merge({}, config, opts || {}); |
|
} |
|
|
|
return new Logger(config); |
|
}; |
|
|
|
module.exports.Logger = Logger; |
|
module.exports.compile = tfunk;
|
|
|