import colors from "ansi-colors"; import { injectable } from "inversify"; import stripAnsi from "strip-ansi"; import winston, { Logger as WinstonLogger } from "winston"; const { combine, timestamp, printf, errors } = winston.format; const logLevelColor: Record = { error: "red", warn: "yellow", info: "green", verbose: "cyan", debug: "blue", }; const customFormat1 = printf(({ level, message, timestamp, context = "App", ...meta }) => { const cleanedMessage = stripAnsi(message as string); return `[${timestamp}] [${context}] [${level.toUpperCase()}]: ${cleanedMessage} ${Object.keys(meta).length ? JSON.stringify(meta, null, 0) : ""}`; }); const customFormat2 = printf(({ level, message, timestamp, context = "App", trace, ...meta }) => { const coloredTimestamp = colors.white(`[${timestamp}]`); const Express = colors.green(`[Express]`); const logLevel = logLevelColor[level]; const coloredLevel = (colors[logLevel] as (str: string) => string)(`[${level.toUpperCase()}]`); const coloredMessage = colors.green(message as string); const coloredContext = colors.yellow(`[${context}]`); const errorTrace = trace instanceof Error ? trace.stack : trace ? JSON.stringify(trace, null, 4) : ""; const metaLog = Object.keys(meta).length ? JSON.stringify(meta, null, 4) : ""; return `${Express} - ${coloredTimestamp} ${coloredLevel} ${coloredContext} : ${coloredMessage} ${errorTrace} ${metaLog}`; }); @injectable() export class Logger { public logger: WinstonLogger; constructor(private context: string = "App") { this.logger = winston.createLogger({ level: process.env.LOGGER_LEVEL || "info", format: combine(errors({ stack: true }), timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), customFormat1), transports: [ // new winston.transports.File({ filename: "logs/combined.log", handleExceptions: true }), // new winston.transports.File({ level: "error", filename: "logs/error.log", handleExceptions: true }), new winston.transports.Console({ level: "debug", format: combine(errors({ stack: true }), timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), customFormat2), // handleExceptions: true, }), // new winston.transports.Http({}), ], exitOnError: false, }); } info(message: any, ...meta: any[]) { this.logger.info({ message, context: this.context, ...meta }); } error(message: any, trace?: any) { this.logger.error({ message, trace, context: this.context }); } warn(message: any, ...meta: any[]) { this.logger.warn({ message, context: this.context, ...meta }); } debug(message: any, ...meta: any[]) { this.logger.debug({ message, context: this.context, ...meta }); } verbose(message: any, ...meta: any[]) { this.logger.verbose({ message, context: this.context, ...meta }); } }