How to add className on console log?? (How do I know where the log originates?)

37 Views Asked by At

I used two logger Winston & NestJS Logger

NestJS Logger is easily show class_name But Winston isn't

NestJS Logger ProcessService is ClasssName

Winston Logger enter image description here

I want to use Winston Logger showing class_name

  • logger.js
'use strict'

const logDir = 'logs'

const getLabel = function (callingModule: NodeModule) {
    const parts = callingModule.filename.split(path.sep)

    return parts[parts.length - 1]
}

const logFormat = printf(({ timestamp, label, level, message, ...metadata }) => {
    let msg = `${timestamp}` + ` ${label} ${level}: [${getLabel(module)}] ${message}`

    if (metadata.length > 0) {
        msg += JSON.stringify(metadata)
    }
    return msg
})

const colorizer = winston.format.colorize()

const logger = winston.createLogger({
    level: 'debug',
    format: combine(
        label({
            label: 'Test_v1'
        }),
        timestamp({
            format: 'YYYY-MM-DD HH:mm:ss'
        }),
        colorize({
            all: true,
            level: true,
            message: true,
            colors: { info: 'green', error: 'red', http: 'blue' }
        }),

        logFormat
    ),
    transports: [
        new winston.transports.Console(),
        new winstonDaily({
            level: 'info',
            datePattern: 'YYYY-MM-DD',
            dirname: logDir,
            filename: `%DATE%.log`,
            maxFiles: 30,
            zippedArchive: true
        })
    ]
})
export default logger

- whatever.ts

and i call logger like this

import log from '@/common/logger'

...

log.info("test")

my expected result is

2024-03-07 16:50:46 Test_v1 info: [whatever] test

but i got

2024-03-07 16:50:46 Test_v1 info: [logger.js] test

Should I put it in as a parameter directly?

1

There are 1 best solutions below

0
Анар Лятифов On

I have two answers for you:

  1. better way would be use nestjs Logger:
import {Injectable, Logger} from "@nestjs/common";

@Injectable()
export class AppService {
    private readonly logger: Logger = new Logger(AppService.name)

    doSomething(){
        this.logger.log("Very important stuff")
    }
}

so this will outputs: [Nest] 52 - 03/08/2024, 7:19:06 PM LOG [AppService] Very important stuff

But if you still want to trace file then:

I`m not sure how to correct use it to winston but one obvious way will be:

-- logger.ts


//your winston config stuff

declare const __stack: NodeJS.CallSite[];

Object.defineProperty(global, '__stack', {
    get: function() {
        const orig = Error.prepareStackTrace;
        Error.prepareStackTrace = function(_, stack) {
            return stack;
        };
        const err = new Error;
        Error.captureStackTrace(err);
        const stack = err.stack;
        Error.prepareStackTrace = orig;
        
        return stack;
    }
});


const getTraceInfo = () => {              
    const stack = __stack.at(3);
    const fileName = stack.getFileName().split("/").slice(-2).join("/");
    const line = stack.getLineNumber()
    return `${fileName}:${line}`
}

export default {
    log: (...args: string[]) => {
        
        return logger.log(`[${getTraceInfo()}]`,...args)
    }
}

not a best solution, but it will works and output this:

2024-03-07 16:50:46 Test_v1 info: [logger.js] [app/app.module.js:25] Sirius stuff

I guess you can just edit your getLabel and you will not need to overwrite export