import { env } from "process"; import { inspect } from "util"; import { bimap } from "../utils"; export interface Logger { trace(...objs: any[]): void; debug(...objs: any[]): void; info(...objs: any[]): void; warn(...objs: any[]): void; error(...objs: any[]): void; } const levels = bimap({ TRACE: 1, DEBUG: 2, INFO: 3, WARN: 4, ERROR: 5 }); class LoggerImpl implements Logger { private level: number; constructor(level: string) { this.level = levels[level] || 1000; } private log(level: number, objs: any[]) { if (this.level <= level) { const prefix: string = levels[level]; const str = objs .map((obj, index) => { if (index === objs.length - 1 && obj instanceof Error) { if (this.level <= levels.DEBUG) { return obj.stack || obj; } else { return obj.message || obj; } } return obj; }) .map(obj => typeof obj === "object" ? inspect(obj, false, null, true) : obj ); console.error.apply(console, [prefix, ...str]); } } trace = (...objs: any[]) => this.log(levels.TRACE, objs); debug = (...objs: any[]) => this.log(levels.DEBUG, objs); info = (...objs: any[]) => this.log(levels.INFO, objs); warn = (...objs: any[]) => this.log(levels.WARN, objs); error = (...objs: any[]) => this.log(levels.ERROR, objs); } export const logger: Logger = new LoggerImpl( env.NODE_ENV === "test" ? "" : (env.LOG_LEVEL || "INFO").toUpperCase() );