Tuesday, September 6, 2011

Modular JavaScript Tracing

UPDATE (2/18/2012) -- I have moved the source code to Codeplex

Much to my chagrin, I have been doing a LOT of JavaScript debugging lately.  In order to handle multple "levels" of debugging information, I started using Ben Alman’s “ba-debug” javascript library (http://benalman.com/projects/javascript-debug-console-log/).

ba-debug is really nice, but it's unfortunately "global", meaning that the setLevel() method and all the messages are switched with a single global switch.  After using it for a while, I decided I needed something more modular.So, I took his library and modified it heavily.

Being a fan of the .NET System.Diagnostics library, including the TraceSource/SourceSwitch objects, I decided to emulate that somewhat. result is the Trace file I’m including here.

Here’s a brief overview of how to use it.

(NOTE: When I say "module", I mean a closure/module as defined by this -- and many other-- article: www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth)

The idea is that, in some sort of module, you do this:

   var _trace = new Trace('ModuleName');

Then, when you want to trace out any level of diagnostics, you do:

   _trace.debug('ItemsListView - redrawing...');

Supported methods are: error, warn, info, debug, log
The current default level is “error” for all Trace objects.

If you want to increase that level for a particular module, you insert a line like this into your web page:

   Trace.traceLevel('ModuleName', Trace.Levels.log);

Trace.Levels contains all the method names and “off” as options.

Additionally, I continue the functionality that ba-debug gives you so you can set a callback function for Trace messages like this:

    Trace.setCallback(function (args) {
        // do something with the arguments array here.
    true, // force it
    50); //  give me the last 50 at most 

  1. A method that receives an array of the arguments that were passed to the trace message (the level should be the first argument in the array).  Pass null to turn it off
  2. Boolean on whether or not to “force” the callback.  If this is true, it will always call the callback for every message.  Otherwise, it will only call the callback if the browser doesn’t support the “window.console.log” method (at the very least).
  3. A limit to the number of messages to be given up front.  Since messages could have accumulated before you call the callback, there may be a flood of messages right away when you set the callback up, so this will stop you from getting too many messages in the beginning.
The 2nd and 3rd parameters are both optional.

The callback will be called for every existing message (up to the optional "limit") and for all subsequent trace messages.  Note also that the callback does NOT get filtered, so it receives all trace messages.

If there is any expressed interest, I can go over the implementation of the object in detail as well in a follow-up post.


Download the whole file here:

No comments:

Post a Comment