Debugging JavaScript applications.

Recently I've been working on a large (for me) JavaScript project that has several levels of nested looping logic. Usually I'd debug this kind of script by using lots of console.log(); commands and then comment them out once I no longer needed them, but having nested loops meant that the number of iterations was in the thousands and even just having one logging command at the lowest level was causing enough messages to be written to the console that it was causing Chrome to hang for a few seconds when opening the inspector.

Another problem I found was that my code was becoming littered with commented out logging code which is never nice from a maintenance perspective and also meant that to re-enable debugging in different areas of the script involved lots of un-commenting and re-commenting of the console.log(); commands.

My Solution

So here's the little solution I came up with, it basically sits in-between your code and the console.log command and watches to see what parameters are passed to it, if they match it's criteria it will dump the message to the console.log(); and once it's reached a pre-determined limit it will stop outputting messages completely so that it doesn't cause any performance issues.

The JavaScript debugging code

var dBug = function(){

	this.debug_mode = false,
	this.debug_count = 0,
	this.debug_limit = 150,		// stop logging after this many calls
	this.debug_functions = [],	// array of the function names to show
	this.debug_levels = [],		// array of the debug_levels to show

	this.log = function(debug_function, debug_level, message){
		// debug_level enables us to turn off certain console messages
		if( this.debug_mode === true ){
			if (this.debug_count >= this.debug_limit ){
				console.log('Log limit (' + this.debug_limit + ') reached');
				this.debug_mode = false; // turn itself off
			} else {
				if ( this.debug_functions.indexOf(debug_function) !== -1 && this.debug_levels.indexOf(debug_level) !== -1 ){
					console.log(message);
					this.debug_count++;
				}
			}
		}
	};

}

How to use it

There are three properties that you can set on the object, which will control how the messages are outputted, these are:

Also, there are three arguments which need to be passed to the log() function, which are as follows;

Example dBug

// setup the debugger
dBug = new dBug();
dBug.debug_mode = true;
dBug.debug_functions = ['testDebugger'];
dBug.debug_levels = [1,2,3];

// just a sample function
function testDebugger(){
	dBug.log('testDebugger', 1, 'before loop');
	for(var i=0; i<=5; i++){
		dBug.log('testDebugger', 2, 'inside first loop [i = ' + i + ']');
		for(var j=0; j<=5; j++){
			dBug.log('testDebugger', 3, 'inside second loop [j = ' + j + ']');
			for(var k=0; k<=5; k++){
				dBug.log('testDebugger', 4, 'inside third loop [k = ' + k + ']');
			}
		}
	}
	dBug.log('testDebugger', 1, 'after loop');
}


// run the sample function
testDebugger();

This will output the following messages to the console.

before loop
inside first loop [i = 0]
inside second loop [j = 0]
inside second loop [j = 1]
inside second loop [j = 2]
inside second loop [j = 3]
inside first loop [i = 1]
inside second loop [j = 0]
inside second loop [j = 1]
inside second loop [j = 2]
inside second loop [j = 3]
inside first loop [i = 2]
inside second loop [j = 0]
inside second loop [j = 1]
inside second loop [j = 2]
inside second loop [j = 3]
inside first loop [i = 3]
inside second loop [j = 0]
inside second loop [j = 1]
inside second loop [j = 2]
inside second loop [j = 3]
after loop
By Karl Payne

Comments

There are no comments, don't be shy, somebody has to be first.

Leave a comment