import winston, { Logform } from "winston"; import path from "path"; import { subDays } from "date-fns"; import { InDev, LogsRoot, InTest } from "../config/Env"; import { log } from "./Function"; const printf = (info: Logform.TransformableInfo) => { const errorCode = info.code ? ` | ${info.code}` : ""; const logType = info.type ? ` | ${info.type}` : ""; return `${info.timestamp} [${info.level?.toUpperCase()}${logType}${errorCode}]: ${info.message}`; }; export default class Logger { private logger: winston.Logger; constructor(model: string, defaultFormat: (info: Logform.TransformableInfo) => string = printf) { // Create the logger with the defined transports this.logger = winston.createLogger({ transports: [ new winston.transports.File({ level: "silly", filename: path.join(LogsRoot, model + ".log"), format: winston.format.combine( winston.format.timestamp(), winston.format.json() //,winston.format.printf(printf) ), }), // Conditional console transport for development ...(InDev ? [ new winston.transports.File({ level: "silly", filename: path.join(LogsRoot, model + ".dev.log"), format: winston.format.combine( winston.format.timestamp(), winston.format.printf(defaultFormat) ), }), new winston.transports.Console({ level: "silly", format: winston.format.combine( winston.format.timestamp(), winston.format.printf(defaultFormat) ), }), ] : []), ], }); // Event listener for 'log' event this.logger.on("log", (logInfo) => { // Your custom handling logic for the log log(`${model} Log event emitted: ${logInfo}`); }); // Event listener for 'error' event this.logger.on("error", (error) => { // Your custom handling logic for the error console.error(`${model} Error event emitted: `, error); }); // Event listener for 'finish' event this.logger.addListener("finish", () => { // Your custom handling logic after the logger finishes processing a log message log(`${model} Finish event emitted`); }); } onFinish(callback: () => void) { this.logger.on("finish", callback); } async ReadLogs(logLevel: string, numDaysFrom: number = 1, numDaysTo: number = 0) { const from = subDays(new Date(), numDaysFrom); const to = subDays(new Date(), numDaysTo); try { return await new Promise((resolve, reject) => { //@ts-ignore this.logger.query({ level: logLevel, from, until: to }, (err, results) => { if (err) reject(err); else resolve(results.file); }); }); } catch (e) { globalLogger.error((e as Error).message, { code: 0, type: "Reading Logs" }); } /* )*/ } error(message: string, meta?: any) { this.logger.log("error", message, meta); } warn(message: string, meta?: any) { this.logger.log("warn", message, meta); } http(message: string, meta?: any) { this.logger.log("http", message, meta); } info(message: string, meta?: any) { if (InTest) return; this.logger.log("info", message, meta); } verbose(message: string, meta?: any) { this.logger.log("verbose", message, meta); } debug(message: string, meta?: any) { if (InTest) return; log("debug :", { message, meta }); this.logger.debug(message, meta); } silly(message: string, meta?: any) { this.logger.log("silly", message, meta); } } export const globalLogger = new Logger("global");