All files / services LoggerService.js

85.18% Statements 69/81
46.15% Branches 6/13
80% Functions 4/5
85.18% Lines 69/81

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 811x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 31x 31x 31x 31x 1x 1x 1x 1x 1x     1x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 15x 15x 1x 1x           1x
import console from "node:console";
// https://betterstack.com/docs/logs/javascript/winston/
import winston from "winston";
import {Logtail} from "@logtail/node";
import {LogtailTransport} from "@logtail/winston";
import {isSet} from "../lib/Common.js"; // https://betterstack.com/docs/logs/javascript/winston/
export default class LoggerService {
    constructor(config) {
        this.config = config;
        this.buildLogtail();// https://logs.betterstack.com/ (ex. logtail) service
        this.buildLogger();// https://github.com/winstonjs/winston logger that could embed logtail transport
    }
 
    buildLogtail() {
        this.logtail = null;
        // Create a Logtail client
        let sourceToken = this.config?.log?.logtailToken;
        if (isSet(sourceToken)) {
            this.logtail = new Logtail(sourceToken);
        }
    }
 
 
    buildLogger() {
        const format = winston.format;
        winston.addColors({
            info: 'white',
            error: 'red',
            warn: 'yellow',
            debug: 'cyan'
        });
 
        // https://stackoverflow.com/questions/10271373/node-js-how-to-add-timestamp-to-logs-using-winston-library
        // Limitations: if you colorize all: true or level: true then the padEnd on level is not applied. If you use format.align, this align only the message start part..
        const consoleTransport = new winston.transports.Console({
            "format": format.combine(
                format.colorize({message: true}),
                format.timestamp({
                    format: 'DD-MM-YYYY HH:mm:ss.SSS'
                }),
                format.printf(info => {
                    const labelInfo = isSet(info.label) ? ` 🧾️${info.label} -` : "";// logger name from class init
                    const userInfo = isSet(info.remoteAddress) ? ` πŸ‘€ ${info.remoteAddress}` : "";// for api call : remote address
                    const pluginInfo = isSet(info.pluginName) ? ` πŸ–₯️ ${info.pluginName} ` : "";// for plugin business : plugin name
                    return `${info.timestamp} [${info.level.padEnd(5)}]${labelInfo}${pluginInfo}${userInfo} ${info.message}`;
                })
            )
        });
        let isDebugLevelActivated = process.env["BES_DEBUG"] === "true";
        if (isDebugLevelActivated) {
            consoleTransport.level = 'debug';
        }
 
        if (isSet(this.logtail)) { // https://logs.betterstack.com
            const transports = [new LogtailTransport(this.logtail), consoleTransport];
            this._winstonLogger = winston.createLogger({transports});
            console.log(` β˜‘  winston logtail logger${isDebugLevelActivated ? " with console in debug level" : ""}`);
        } else {
            const transports = [consoleTransport];
            this._winstonLogger = winston.createLogger({transports});
            console.log(` β˜‘  winston console logger${isDebugLevelActivated ? " with console in debug level" : ""}`);
        }
    }
 
    /**
     * to use in service/class init to bootstrap a logger
     * doc: https://github.com/winstonjs/winston?tab=readme-ov-file#creating-child-loggers
     * example: this.logger = loggerService.getLogger().child({ label: 'ExpressServer' });
     * @returns {winston.Logger | *}
     */
    getLogger() {
        return this._winstonLogger;
    }
 
    flush() {
        if (this.logtail === null) {
            return Promise.resolve;
        }
        return this.logtail.flush();
    }
}