cordis/logger/logger.ts

117 lines
3.9 KiB
TypeScript
Raw Normal View History

2021-10-30 17:26:41 +00:00
import * as moment from 'moment';
import * as colors from 'colors/safe';
import * as util from 'util';
import * as path from 'path';
import * as StackTrace from '../stack-trace/stack-trace';
/**
* Pads a string toward the center
* @param x The value to pad
* @param p The padding to use
* @param n The end-length of the string
* @returns The padded string
*/
function padCenter(x: string, p: string, n: number) {
let z = false;
while (x.length < n) {
if (z) {
z = false;
x = p + x;
} else {
z = true;
x = x + p;
}
}
return x;
}
enum LoggerLevel {
Fatal,
Error,
Warn,
Info,
Debug,
Silly
};
/**
* Colorizes text
* @param level The color level
* @param text The text to colorize
* @returns The colored text
*/
function colorize(level: LoggerLevel, text: string): string {
switch (level) {
case LoggerLevel.Fatal: return colors.bgRed(colors.white(text));
case LoggerLevel.Error: return colors.red(text);
case LoggerLevel.Warn: return colors.yellow(text);
case LoggerLevel.Info: return colors.green(text);
case LoggerLevel.Debug: return colors.blue(text);
case LoggerLevel.Silly: return colors.magenta(text);
default: return colors.bgWhite(text);
}
}
export default class Logger {
private name: string;
private console: Console;
constructor(name: string, processConsole?: Console) {
this.name = name;
this.console = processConsole ?? console;
}
private log(level: LoggerLevel, message: string | null, data?: Error | any): void {
let frames: StackTrace.Frame[] = StackTrace.parse(new Error());
let frame = frames[1];
let filePath = frame.fileName;
let lineNumber = frame.lineNumber;
let nameDisplay = filePath ? path.relative(path.join(__dirname, '..'), filePath) : this.name;
// this.name;
let prefix: string = `[ ${colorize(level, padCenter(LoggerLevel[level].toLowerCase(), ' ', 5))} | ${nameDisplay}:${lineNumber} | ${moment().format('HH:mm:ss.SSS')} ]`;
let out: string = '';
if (message !== null) {
out += message.split('\n').map(o => `${prefix}: ${o}`).join('\n');
}
function handleData(data: Error | any) {
if (data) {
if (message !== null) {
out += '\n';
}
if (data instanceof Error) {
if (data.stack) {
out += `${prefix}# ${data.stack.split('\n').join(`\n${prefix}# `)}`;
} else {
out += `${prefix}# ${data.name}: ${data.message}`;
}
} else {
let s = util.inspect(data, { colors: true });
s = s.split('\n').map(o => `${prefix}$ ${o}`).join('\n');
out += s;
}
}
}
if (Array.isArray(data)) {
data.forEach(handleData);
} else {
handleData(data);
}
this.console.log(out);
}
public fatal(message: string | null, data?: Error | any): void { this.log(LoggerLevel.Fatal, message, data); }
public error(message: string | null, data?: Error | any): void { this.log(LoggerLevel.Error, message, data); }
public warn( message: string | null, data?: Error | any): void { this.log(LoggerLevel.Warn, message, data); }
public info( message: string | null, data?: Error | any): void { this.log(LoggerLevel.Info, message, data); }
public debug(message: string | null, data?: Error | any): void { this.log(LoggerLevel.Debug, message, data); }
public silly(message: string | null, data?: Error | any): void { this.log(LoggerLevel.Silly, message, data); }
public inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string {
return util.inspect(object, showHidden, depth, color);
}
}