Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access line numbers when wrapping Firebug (or similar) Console api

I have wrapped the console API to provide granular logging levels as well as few other sugar features.

This works fine, the only problem is that firebug (or whatever other console) will always report the line number the log came from as the line the console API itself is invoked.

How would you suggest I make the console log the line number at which I call my wrapper function?

I would prefer a cross browser solution but failing that a firebug plugin could be a good start.

fyi I call my loging function like so:

db.log(db.LogLevel.WARN, "Blah Blah Blah");
like image 778
Ollie Edwards Avatar asked Jul 26 '10 15:07

Ollie Edwards


2 Answers

Interesting problem... I may have a hack for you. I can't test this right now, but I think it might work.

We know that a regular function call won't work, so I started thinking about #defines in C and macros in various other languages. Unfortunately, javascript doesn't have this, but perhaps an eval hack will work. I'm expecting that eval will run the code as if it came from the same line - if not, bleh, ignore the rest of this answer.

My method works like this:

  1. Change your db.log function to point to eval (yes, ew)
  2. Instead of passing in your LogLevels as an argument, create functions for each of them that returns a string with console.log in it and a custom message.

It should look something like this:

db = {LogLevel: {}};
db.log = eval;
db.LogLevel.warn = function(message) {
   return "console.log('THIS IS A WARNING: " + message + "');";
};

You should be able to call it like this now:

db.log(db.LogLevel.warn("Blah blah blah"));
like image 169
David Tang Avatar answered Sep 29 '22 23:09

David Tang


//trust me, this way rocks!  Auto prepend a logHead, yet keep correct line number displayed debug view.
//Output sample:
//  5/10 1:13:52.553  hi                                    a.js:100
//  5/10 1:13:52.553  err                                   b.js:200

    var Log = {
        debug : true,

        /*
         * log.d(logData1, logData2, ...)
         *  --> console.log( getLogHead(), logData1, logData2, ...)
         * 
         * @comment Using bind and property accesser
         * @see http://ejohn.org/blog/javascript-getters-and-setters/
         */
        get d() { 
            if ( !this.debug) return _emptyFunc;
            return console.log.bind( console, this._getLogHeader() );
        },

        /*
         * output error info
         */
        get e() { 
            return console.error.bind( console, this._getLogHeader() );
        },

        /**
         * get current time in 01/31 23:59:59.999 format
         */
        _getLogHeader : function () {

            var millisec = Date.now();
            this._dtNow.setTime( millisec );
            //toLocaleString is 2013/01/31 23:59:59
            return this._dtNow.toLocaleString().slice( 5 ) + '.' + ('000' + millisec).slice( -3 ) + ' ';
        },
        _dtNow: new Date(),
        _emptyFunc: function() {}
    };


    //enjoy it !
        Log.d('hi');
        Log.e('err');
like image 37
osexp2003 Avatar answered Sep 30 '22 00:09

osexp2003