137 lines
4.4 KiB
TypeScript
137 lines
4.4 KiB
TypeScript
import config from "config";
|
|
import {v4 as uuid} from "uuid";
|
|
import Log from "./models/Log";
|
|
import {bufferToUUID} from "./Utils";
|
|
|
|
export default class Logger {
|
|
private static logLevel: LogLevelKeys = <LogLevelKeys>config.get<string>('log_level');
|
|
private static dbLogLevel: LogLevelKeys = <LogLevelKeys>config.get<string>('db_log_level');
|
|
private static verboseMode: boolean = false;
|
|
|
|
public static verbose() {
|
|
this.verboseMode = true;
|
|
this.logLevel = <LogLevelKeys>LogLevel[LogLevel[this.logLevel] + 1] || this.logLevel;
|
|
this.dbLogLevel = <LogLevelKeys>LogLevel[LogLevel[this.dbLogLevel] + 1] || this.dbLogLevel;
|
|
Logger.info('Verbose mode');
|
|
}
|
|
|
|
public static isVerboseMode(): boolean {
|
|
return this.verboseMode;
|
|
}
|
|
|
|
public static silentError(error: Error, ...message: any[]): string {
|
|
return this.log('ERROR', message, error, true) || '';
|
|
}
|
|
|
|
public static error(error: Error, ...message: any[]): string {
|
|
return this.log('ERROR', message, error) || '';
|
|
}
|
|
|
|
public static warn(...message: any[]) {
|
|
this.log('WARN', message);
|
|
}
|
|
|
|
public static info(...message: any[]) {
|
|
this.log('INFO', message);
|
|
}
|
|
|
|
public static debug(...message: any[]) {
|
|
this.log('DEBUG', message);
|
|
}
|
|
|
|
public static dev(...message: any[]) {
|
|
this.log('DEV', message);
|
|
}
|
|
|
|
private static log(level: LogLevelKeys, message: any[], error?: Error, silent: boolean = false): string | null {
|
|
const levelIndex = LogLevel[level];
|
|
if (levelIndex <= LogLevel[this.logLevel]) {
|
|
if (error) {
|
|
if (levelIndex > LogLevel.ERROR) this.warn(`Wrong log level ${level} with attached error.`);
|
|
} else {
|
|
if (levelIndex <= LogLevel.ERROR) this.warn(`No error attached with log level ${level}.`);
|
|
}
|
|
|
|
const computedMsg = message.map(v => {
|
|
if (typeof v === 'string') {
|
|
return v;
|
|
} else {
|
|
return JSON.stringify(v, (key: string, value: any) => {
|
|
if (value instanceof Object) {
|
|
if (value.type === 'Buffer') {
|
|
return `Buffer<${Buffer.from(value.data).toString('hex')}>`;
|
|
} else if (value !== v) {
|
|
return `[object Object]`;
|
|
}
|
|
}
|
|
if (typeof value === 'string' && value.length > 96) {
|
|
return value.substr(0, 96) + '...';
|
|
}
|
|
return value;
|
|
}, 4);
|
|
}
|
|
}).join(' ');
|
|
|
|
const shouldSaveToDB = levelIndex <= LogLevel[this.dbLogLevel];
|
|
|
|
let output = `[${level}] `;
|
|
const pad = output.length;
|
|
|
|
const logID = Buffer.alloc(16);
|
|
uuid({}, logID);
|
|
let strLogID = bufferToUUID(logID);
|
|
if (shouldSaveToDB) output += `${strLogID} - `;
|
|
|
|
output += computedMsg.replace(/\n/g, '\n' + ' '.repeat(pad));
|
|
|
|
switch (level) {
|
|
case "ERROR":
|
|
if (silent || !error) {
|
|
console.error(output);
|
|
} else {
|
|
console.error(output, error);
|
|
}
|
|
break;
|
|
case "WARN":
|
|
console.warn(output);
|
|
break;
|
|
case "INFO":
|
|
console.info(output);
|
|
break;
|
|
case "DEBUG":
|
|
case "DEV":
|
|
console.debug(output);
|
|
break;
|
|
}
|
|
|
|
if (shouldSaveToDB) {
|
|
const log = Log.create({});
|
|
log.setLevel(level);
|
|
log.message = computedMsg;
|
|
log.setError(error);
|
|
log.setLogID(logID);
|
|
log.save().catch(err => {
|
|
if (!silent && err.message.indexOf('ECONNREFUSED') < 0) {
|
|
console.error({save_err: err, error});
|
|
}
|
|
});
|
|
}
|
|
return strLogID;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private constructor() {
|
|
}
|
|
}
|
|
|
|
export enum LogLevel {
|
|
ERROR,
|
|
WARN,
|
|
INFO,
|
|
DEBUG,
|
|
DEV,
|
|
}
|
|
|
|
export type LogLevelKeys = keyof typeof LogLevel;
|