I provide a class to use but for convenience I want the class to implement some instance methods as static methods. This was fast and concise but it feels smelly, probably because I'm modifying the class after I create an instance of it. Is this ok?
const logLevel = !args['v'] || args['v'] === true ? 0 : parseInt(args['v']);
const chalk = new Chalk.constructor({enabled: useColor});
const nameLength = args['format-name-length'] || 25;
class Logger{
constructor(name='', _stdout=stdout, _stderr=stderr){
this._name = this._getPaddedName(name);
this._stdout = _stdout;
this._stderr = _stderr;
this.error.bind(this);
this.info.bind(this);
this.warn.bind(this);
}
error(level, ...args){
if(level <= logLevel){
this._print(this._stderr, args, 'red', level);
}
}
info(level, ...args){
if(level <= logLevel){
this._print(this._stdout, args, 'blue', level);
}
}
warn(level, ...args){
if(level <= logLevel){
this._print(this._stderr, args, 'yellow', level);
}
}
_getLogId(color, level){
return chalk[color](
moment().format("YYYY:MM:DD h:mm:ss")
+ ` ${this._name}`
+ ` [${level}]: `
);
}
_getPaddedName(name){
let nameArray = name.split('')
.slice(0, nameLength);
if(nameLength > name.length){
nameArray = nameArray
.concat(new Array(nameLength - name.length).fill(null));
}
let ellipsis = nameArray.slice(nameLength - 3)
.reduce((prev, next)=>!!(prev || next), false);
return nameArray
.slice(0, nameLength - 3)
.map(char=>char || '-')
.concat(ellipsis ? ['.', '.', '.'] : ['-', '-', '-'])
.join('');
}
_format(arg, color, level){
let logId = this._getLogId(color, level);
return util.format(arg)
.replace(/^/, logId)
.replace(/(\r?\n)/g, `\n${logId}`)
.replace(/((?:\r?\n)?$)/, '\n');
}
_print(stream, args, color, level){
args.forEach(arg=>{
if(arg !== ''){
stream.write(this._format(arg, color, level));
}
});
}
}
let defaultLogger = new Logger('logger');
Logger.error = defaultLogger.error.bind(defaultLogger);
Logger.info = defaultLogger.info.bind(defaultLogger);
Logger.warn = defaultLogger.warn.bind(defaultLogger);
return Logger;