Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript: console log use parent scope

Is it possible using some javascript trickery to tell console.log which line number it should output?

Suppose, we the following simple example:

function Logger () {
    this.debug = function(msg) {
        // do some stuff with msg
        console.log(msg);
    };
}

var log = new Logger();
log.debug("Hello");

If you open the page, Chrome shows up this:

enter image description here

This indicates that the message was logged at main.js:4 but what I really want is that it shows main.js:9. Because line 9 is where the logger was called. For this simple case it doesn't make much difference, but when the Logger is in a separate file, it always shows logger.js instead of the class which called the logger.

The Logger class should do some additional stuff with the logged message (e.g. sending it to the server), thus I can't just use this.debug = console.log.

EDIT:

There are already some similar questions, but all of them just add an additional line to the output, which isn't clickable to jump to the corresponding line:

  • Extending console.log without affecting log line
  • console.log wrapper that keeps line numbers and supports most methods?
  • Get console wrapper to log message on correct line
  • Getting Chrome's console.log to display the line that called a function
  • Custom console.log that keeps line number
  • Intercept console.log but keep stack
  • https://stackoverflow.com/questions/28457477/javascript-console-log-change-line-number-to-somewhere-higher-in-the-stack?rq=1
like image 433
Stefan Profanter Avatar asked Aug 27 '15 14:08

Stefan Profanter


1 Answers

The first thing that comes to my mind is creating a new Error object to get the stack trace and then find the line that called your method, like this:

function Logger () {
    this.debug = function(msg) {
        // do some stuff with msg

        //TODO: document this line
        var callerLine = new Error().stack.split('\n')[2];
        console.log(msg, callerLine);
    };
}

var log = new Logger();
log.debug("Hello");

Basically I'm splitting the error's stack in each newline and ignoring the first and second lines (The error message and your own method in the stack, respectively).

like image 74
William Barbosa Avatar answered Oct 22 '22 12:10

William Barbosa