Home > javascript > log() - A lightweight wrapper for console.log

log() - A lightweight wrapper for console.log

There are a few things that a console.log wrapper can and should do:

  • Prevent errors if a console isn't around (i.e. IE)
  • Maintain a history of logs, so you can look in the past if your console is added afterwards (e.g. firebug lite)
  • Normalize the browser differences in console integration (e.g. when passing multiple arguments into console.log())
  • For something you type regularly, make it quicker to type for the lazy among us.

But there are a few considerations…

Console.log.apply doesn't handle multiple arguments in Safari 3 or Chrome 1.1

Firebug, Chrome, and Safari have a clearer presentation for strings when inside an array:

However while the improved array-wrapped presentation is nice, nested arrays get truncated:

Truncation is no good, so here we avoid array-wrapping when we can.

Extra features

  • A reverse-chronological history, accessible as an array at log.history
  • I have also included a shorthand logargs() function that is useful when you're inside a function and want to know the context and arguments passed in. I use it a lot in ajax callbacks. Worth noting that it uses arguments.callee.caller, which will be deprecated in ECMAScript 5 Strict mode. :(

The code:

 
window.log = function(){
 
  // store logs to an array for reference
  log.history = log.history || [];
  log.history.push(arguments);
 
  window.console && console.log[console.firebug ? 
    'apply' : 'call'](console,Array.prototype.slice.call(arguments));
}
 
// logargs(this); == console.log(this,arguments);
window.logargs = function(context){
  // grab the calling functions arguments
  log(context,arguments.callee.caller.arguments); 
}

And if you'd like it minified:

window.log=function(){var a="history";log[a]=log[a]||[];log[a].push(arguments);window.console&&console.log[console.firebug?"apply":"call"](console,Array.prototype.slice.call(arguments))};window.logargs=function(a){log(a,arguments.callee.caller.arguments)};

Interestingly, the minified version of this script is smaller (262 bytes), and arguably more useful, than the minified firebugx.js, which I've covered before. Plus it has quite a few more features.

Demo?

log() and logargs() demo

Plus Firebug lite?

You got it. This bookmarklet will add firebug lite, and then output the logged history when it's ready:
>>> Fbug Lite+log <<<

Want more power?

After writing this, I worked with Ben Alman on a more comprehensive and robust logging script. It's excellent if you take full advantage of the console API. And you should be aware that Safari 4 and Chrome 2 have most of that API supported. Make full use of it and don't you dare type another alert()!

Paul Irish javascript

  1. | #1

    This code is public domain, btw.

  2. | #2

    Paul, using every minification technique I could think of, I came up with this:

     
    (function(){
      var log,
        history,
        window = this,
        con = window.console;
     
      window.log = log = function() {
        history.push( arguments );
     
        con && con.log[ con.firebug ? 
          'apply' : 'call']( con, Array.prototype.slice.call( arguments ) );
      };
     
      window.logargs = function( context ) {
        log( context, arguments.callee.caller.arguments );
      };
     
      log.history = history = [];
     
    })();
     
    // Minified, it's only 242 bytes, a nearly 8% savings in bandwidth!
     
    (function(){var b,d,c=this,a=c.console;c.log=b=function(){d.push(arguments);a&&a.log[a.firebug?"apply":"call"](a,Array.prototype.slice.call(arguments))};c.logargs=function(e){b(e,arguments.callee.caller.arguments)};b.history=d=[]})();
  3. | #3

    How about submitting this to the Firebug/Firebug Lite projects so all can benefit? And submitting bugs in Chrome/WebKit/Firebug to fix the array wrapping issue?

  4. | #4

    @"Cowboy" Ben Alman, nice tricks. Thx!

  5. | #5

    Note that I've built this up quite a bit and posted it on my site:

    http://benalman.com/projects/javascript-debug-console-log/

  1. | #1
  2. | #2

For code blocks, use <pre lang="javascript" escaped="true">. css and html4strict are also accepted.

Comments for this post will be closed on 4 June 2010.