MicroHack-Registrations-RestAPI / src / utils / Logger.ts
Logger.ts
Raw
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");