skip to Main Content

I have a Logger class which beautifies the logs before showing them in JS browser console. I use .bind() to let console display correct script name and line (like script_name.ts:62) in the sources instead of always showing Logger.ts:130:

  1. When I use console.log.bind(console, ...args) (correct script name and line):

    expected view

  2. When I call console.log(...args) directly in the Logger.log() function (always the same line in Logger class):

    enter image description here

But there is a problem: I often forgot to call the function returned by Logger.log(). In this case I won’t see any log in the console. Is there any ESLint rule which may help to handle this and show warning when this happens?

Roughly the Logger code is:

class Logger {
  log(...args: any[]) {
    // doing here something with log args
    return console.log.bind(console, ...args);
  }
}

// correct call
Logger.log("some text")();

// incorrect call (nothing will be shown)
Logger.log("some text");

I use this in browser extension in content scripts, this case doesn’t work well with many existing logger libraries.

2

Answers


  1. As far as i know there are no such static code analyzers that could help you.

    Maybe it would worth consider to use .apply() or .call() instead of .bind().

    Login or Signup to reply.
  2. ESLint isn’t really the problem here, your logger function is: if you want to know the actual location where things get logged, rather than trying to bind your way to victory (which is a losing battle), consider capturing the stack trace and removing everything up to and including the Logger.ts entry instead:

    class Logger {
      log(...args) {
        const callStack = (new Error()).stack.split(`n`);
        let cruft = ``;
        do {
          cruft = callStack.shift();
        } while (!cruft.includes(`log`));
    
        // I'm checking for the `log` function name here, as
        // everything in this snippet lives in a single file,
        // but in your code this'd be `Logger.ts` or the like.
    
        // And after this shift loop, callStack[0] is now
        // the "real" location where you called log():
        console.log({
          location: callStack[0].trim(),
          arguments: args
        });
      }
    }
    
    const logger = new Logger();
    
    function weShouldSeeThis() {
      logger.log(`some`, `values`, { a: [1,2,3]});
    }
    
    weShouldSeeThis();

    With this approach, you can craft your logger function to do whatever you need to do (which certainly isn’t console logging from the looks of it – because that’s not the console =) in a way that you can precisely point to where a log action occurred.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search