@pilotlab/lux-debug
Version:
A luxurious user experience framework, developed by your friends at Pilot.
365 lines (310 loc) • 15.4 kB
text/typescript
import is from '@pilotlab/lux-is';
import { Strings } from '@pilotlab/lux-strings';
import { MapList } from '@pilotlab/lux-collections';
import LogFormat from './logFormat';
import Debug from './debug';
import { LogColor, LogType } from './logEnums';
import LogMessage from './logMessage';
import LogConsole from './logConsole';
export class Logger {
constructor() {
this.p_TIME_STAMP_LENGTH = 8;
this.p_SPACE = ' ';
this.p_LABEL_AREA_LENGTH_MAX = 20;
this.p_FILL_SPACES_MIN = 3;
this.p_SPACE_FILLER_START = '';
this.p_SPACE_FILLER = '─';
this.p_INDENT_START = '';
this.p_HEADER_LENGTH = this.p_TIME_STAMP_LENGTH + this.p_SPACE.length + this.p_LABEL_AREA_LENGTH_MAX + (this.p_SPACE.length * 2);
}
isTrace:boolean = false;
static get format():LogFormat {
if (is.empty(this._format)) this._format = new LogFormat();
return this._format;
}
private static _format:LogFormat;
static get time():string {
const today:Date = new Date();
const hour:number = today.getHours();
const minute:number = today.getMinutes();
const second:number = today.getSeconds();
return `${Strings.padDigits(hour, 2)}:${Strings.padDigits(minute, 2)}:${Strings.padDigits(second, 2)}`;
}
static setColor(text:string, color:LogColor):string {
switch(color) {
case LogColor.BLACK:
text = Logger.format.black.value(text);
break;
case LogColor.BLACK_BRIGHT:
text = Logger.format.blackBright.value(text);
break;
case LogColor.BLUE:
text = Logger.format.blue.value(text);
break;
case LogColor.BLUE_BRIGHT:
text = Logger.format.blueBright.value(text);
break;
case LogColor.CYAN:
text = Logger.format.cyan.value(text);
break;
case LogColor.CYAN_BRIGHT:
text = Logger.format.cyanBright.value(text);
break;
case LogColor.GRAY:
text = Logger.format.gray.value(text);
break;
case LogColor.GREEN:
text = Logger.format.green.value(text);
break;
case LogColor.GREEN_BRIGHT:
text = Logger.format.greenBright.value(text);
break;
case LogColor.MAGENTA:
text = Logger.format.magenta.value(text);
break;
case LogColor.MAGENTA_BRIGHT:
text = Logger.format.magentaBright.value(text);
break;
case LogColor.ORANGE:
text = Logger.format.orange.value(text);
break;
case LogColor.RED:
text = Logger.format.red.value(text);
break;
case LogColor.RED_BRIGHT:
text = Logger.format.redBright.value(text);
break;
case LogColor.YELLOW:
text = Logger.format.yellow.value(text);
break;
case LogColor.YELLOW_BRIGHT:
text = Logger.format.yellowBright.value(text);
break;
}
return text;
}
protected p_categories:MapList<string, boolean> = new MapList<string, boolean>();
protected p_TIME_STAMP_LENGTH:number;
protected p_HEADER_LENGTH:number;
protected p_SPACE:string;
protected p_LABEL_AREA_LENGTH_MAX:number;
protected p_FILL_SPACES_MIN:number;
protected p_SPACE_FILLER_START:string;
protected p_SPACE_FILLER:string;
protected p_INDENT_START:string;
get console():LogConsole { return this.p_console; }
protected p_console:LogConsole = new LogConsole();
get tagLengthMax():number { return this.p_tagLengthMax; }
set tagLengthMax(value:number) { this.p_tagLengthMax = value; }
protected p_tagLengthMax:number = 60;
get lineLengthMax():number { return this.p_lineLengthMax; }
set lineLengthMax(value:number) { this.p_lineLengthMax = value; }
protected p_lineLengthMax:number = 120;
setCategoryMode(category:string, isOn:boolean):void {
this.p_categories.set(category, isOn);
}
isCategoryOn(category:string):boolean {
if (is.empty(category, true)) return true;
return this.p_categories.get(category);
}
/**
* Use to assert state which your program assumes to be true.
*
* Example:
*
* log.assert(is.notEmpty(myVariable));
*/
assert(isConditionMet:boolean, message:string, tag?:string, category?:string):boolean {
if (!isConditionMet) this.logType(LogType.ASSERT, message, tag, category);
return isConditionMet;
}
data(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.DATA, message, category); }
error(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.ERROR, message, tag, category); }
info(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.INFO, message, tag, category); }
warn(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.WARNING, message, tag, category); }
log(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.LOG, message, tag, category); }
test(message:any, tag?:string, category?:string):LogMessage { return this.logType(LogType.TEST, message, tag, category); }
logType(type:LogType, message:any, tag?:string, category?:string):LogMessage {
switch(type) {
case LogType.ASSERT:
return this.custom(message, LogType[LogType.ASSERT], LogColor.ORANGE, tag, category);
case LogType.DATA:
return this.custom(JSON.stringify(message), LogType[LogType.DATA], LogColor.BLUE_BRIGHT, Debug.getClassName(message), category);
case LogType.ERROR:
return this.custom(message, LogType[LogType.ERROR], LogColor.RED_BRIGHT, tag, category);
case LogType.INFO:
return this.custom(message, LogType[LogType.INFO], LogColor.CYAN_BRIGHT, tag, category);
case LogType.WARNING:
return this.custom(message, LogType[LogType.WARNING], LogColor.YELLOW_BRIGHT, tag, category);
case LogType.LOG:
return this.custom(message, LogType[LogType.LOG], LogColor.GREEN_BRIGHT, tag, category);
case LogType.TEST:
return this.custom(message, LogType[LogType.TEST], LogColor.MAGENTA_BRIGHT, tag, category);
}
}
custom(message:any, label:string = '', labelColor:LogColor = LogColor.GRAY, tag?:string, category?:string, spinnerCharacter:string = ' '):LogMessage {
if (is.notEmpty(category, true) && !this.isCategoryOn(category)) return new LogMessage(this, label, labelColor, message, 0, tag, category);
if (!message) message = '';
if (!spinnerCharacter || spinnerCharacter === '') spinnerCharacter = ' ';
let error:any = message instanceof Error ? message : new Error(message.toString());
let messageString:string = error ? error.message : '';
let timeStamp:string = Logger.time;
let logString:string = Logger.format.gray.value(timeStamp);
let lineCount:number = 1;
/// Format label
let labelFormatted:string = '';
let labelLengthMax:number = this.p_LABEL_AREA_LENGTH_MAX - this.p_FILL_SPACES_MIN - this.p_SPACE.length;
if (label && label !== '' && typeof label === 'string') {
labelFormatted = label;
if (labelFormatted.length > labelLengthMax) {
labelFormatted = labelFormatted.slice(0, labelLengthMax - 3);
while (labelFormatted.length < labelLengthMax) labelFormatted += '.';
}
}
/// Format filler
let spaceFiller:string = this.p_SPACE + this.p_SPACE_FILLER_START;
let labelFormattedLength:number = labelFormatted.length;
while (spaceFiller.length < this.p_LABEL_AREA_LENGTH_MAX - labelFormattedLength) spaceFiller += this.p_SPACE_FILLER;
if (labelFormatted && labelFormatted !== '') spaceFiller += this.p_SPACE;
else {
for (let i = 0; i < this.p_SPACE.length; i++) {
spaceFiller += this.p_SPACE_FILLER;
}
}
logString += Logger.format.gray.value(spaceFiller);
switch(labelColor) {
case LogColor.BLACK:
logString += Logger.format.bold.black.value(labelFormatted);
break;
case LogColor.BLACK_BRIGHT:
logString += Logger.format.bold.blackBright.value(labelFormatted);
break;
case LogColor.BLUE:
logString += Logger.format.bold.blue.value(labelFormatted);
break;
case LogColor.BLUE_BRIGHT:
logString += Logger.format.bold.blueBright.value(labelFormatted);
break;
case LogColor.CYAN:
logString += Logger.format.bold.cyan.value(labelFormatted);
break;
case LogColor.CYAN_BRIGHT:
logString += Logger.format.bold.cyanBright.value(labelFormatted);
break;
case LogColor.GRAY:
logString += Logger.format.bold.gray.value(labelFormatted);
break;
case LogColor.GREEN:
logString += Logger.format.bold.green.value(labelFormatted);
break;
case LogColor.GREEN_BRIGHT:
logString += Logger.format.bold.greenBright.value(labelFormatted);
break;
case LogColor.MAGENTA:
logString += Logger.format.bold.magenta.value(labelFormatted);
break;
case LogColor.MAGENTA_BRIGHT:
logString += Logger.format.bold.magentaBright.value(labelFormatted);
break;
case LogColor.ORANGE:
logString += Logger.format.bold.orange.value(labelFormatted);
break;
case LogColor.RED:
logString += Logger.format.bold.red.value(labelFormatted);
break;
case LogColor.RED_BRIGHT:
logString += Logger.format.bold.redBright.value(labelFormatted);
break;
case LogColor.YELLOW:
logString += Logger.format.bold.yellow.value(labelFormatted);
break;
case LogColor.YELLOW_BRIGHT:
logString += Logger.format.bold.yellowBright.value(labelFormatted);
break;
}
/// Format tag
let tagFormatted:string = '';
if (tag && typeof tag === 'string') {
tagFormatted = tag;
if (tagFormatted.length > this.tagLengthMax) {
tagFormatted = tagFormatted.slice(0, this.tagLengthMax - 3);
while (tagFormatted.length < this.tagLengthMax) tagFormatted += '.';
}
tagFormatted = this.p_SPACE + this.p_SPACE + Logger.format.gray.value(`${tagFormatted}`);
}
logString += ' ' + spinnerCharacter;
/// Format message
if (messageString.length > this.lineLengthMax) {
let messageLines:string[] = [];
let tabSpace:string = '';
while (tabSpace.length < (timeStamp.length + this.p_SPACE.length)) tabSpace += ' ';
tabSpace += this.p_INDENT_START;
while (tabSpace.length < this.p_HEADER_LENGTH) tabSpace += ' ';
messageLines = Strings.getLines(messageString, this.lineLengthMax);
lineCount = messageLines.length;
logString += this.p_SPACE + messageLines[0];
logString += tagFormatted + '\n';
for (let i = 1; i < messageLines.length; i++) {
logString += Logger.format.gray.value(`${tabSpace}`) + messageLines[i] + '\n';
}
} else {
logString += this.p_SPACE + (messageString && messageString !== '' ? Logger.format.whiteBright.value(messageString) : Logger.format.gray.value('null, undefined, or empty message'));
logString += tagFormatted;
}
console.log(logString);
/// Format trace info
if (this.isTrace && error.stack) {
let traceString:string = error.stack.toString();
let traceStringFormatted:string = '';
if (traceString.length > this.lineLengthMax) {
let tabSpace:string = '';
while (tabSpace.length < this.p_HEADER_LENGTH) tabSpace += ' ';
let traceLines:string[] = Strings.getLines(traceString, this.lineLengthMax);
for (let i = 0; i < traceLines.length; i++) {
traceStringFormatted += tabSpace + Logger.format.bgBlackBright.value(Logger.format.white.value(traceLines[i])) + '\n';
}
} else {
traceStringFormatted +=
this.p_SPACE + this.p_SPACE + (traceString && traceString !== '' ?
Logger.format.whiteBright.value(traceString) :
Logger.format.gray.value('null, undefined, or empty message'));
}
console.log('');
console.log(traceStringFormatted);
console.log('');
}
let logMessage:LogMessage = new LogMessage(this, label, labelColor, message, lineCount, tag, category, this.p_HEADER_LENGTH);
return logMessage;
}
// messageBlock(message:any, label:string = '', labelColor:LogColor = LogColor.GRAY, tag?:string, category?:string, spinnerCharacter:string = ' '):LogMessage {
// let error:any = message instanceof Error ? message : new Error(message.toString());
// let messageString:string = error ? error.message : '';
//
// /// Format message
// if (messageString.length > this.lineLengthMax) {
// let messageLines:string[] = [];
// let tabSpace:string = '';
//
// while (tabSpace.length < (this.p_TIME_STAMP_LENGTH + this.p_SPACE.length)) tabSpace += ' ';
// tabSpace += this.p_INDENT_START;
// while (tabSpace.length < this.p_HEADER_LENGTH) tabSpace += ' ';
//
// messageLines = Strings.getLines(messageString, this.lineLengthMax);
// lineCount = messageLines.length;
//
// logString += this.p_SPACE + messageLines[0];
// logString += tagFormatted + '\n';
//
// for (let i = 1; i < messageLines.length; i++) {
// logString += Logger.format.gray.value(`${tabSpace}`) + messageLines[i] + '\n';
// }
// } else {
// logString += this.p_SPACE + (messageString && messageString !== '' ? Logger.format.whiteBright.value(messageString) : Logger.format.gray.value('null, undefined, or empty message'));
// logString += tagFormatted;
// }
//
// let logMessage:LogMessage = new LogMessage(this, label, labelColor, message, lineCount, tag, category, this.p_HEADER_LENGTH);
// return logMessage;
// }
} // End class
export default Logger;