Reputation: 25054
In my web-app( heavy on client side, light on server side), while in development, I need to do a lot of debugging, console.log
is very helpful, but ideally in production, there must not be any debug message shown, so I am planning to add the below code:
window.production = false; // set to true when in production mode.
if(window.production){
window.log = function(){};
}else{
window.log = function(){
console.log.apply(console, arguments);
};
}
//then replace all console.log(a, b, c, ...) into window.log(a, b, c, ...) in my code.
is this a good way to make debugging configurable, or must I just make a grunt
that removes all console.log
lines for production?
Upvotes: 2
Views: 1256
Reputation: 670
So if your only end goal is to not show debug messages in production you have a huge amount of options to choose from! You should also decide if the following are important to you:
At a very basic level simply calling
if (window.console && window.console.log)
{
window.log = console.log.bind(console); // function devnull() { };
}
else
{
window.log = function() { };
}
log('This is a log!');
will be enough to allow you to turn logging on/off. This would fulfill goal (5) in the list above and works quite well.
An alternate solution which works well with minifiers like uglify which can remove dead code would be to surround your logging statements with something like (you may not want to pollute the global namespace however):
window.LogLevels =
{
Off: 0x00000000,
Error: 0x00000001,
Warning: 0x00000002,
Timing: 0x00000004,
Data: 0x00000008,
Status: 0x00000010,
...
Verbose: 0x04000000,
};
window.LogLevel = LogLevels.Error | LogLevels.Warning;
window.ShouldLog = function(mask)
{
return ((window.LogLevel & mask) === mask);
};
if (ShouldLog(LogLEvels.Error)) { log('This is an error!'); }
This would satisfy condition (1), (3), and (4) and sets you up to solve (2) as well at the cost of (5).
Coupled with a pre-defined DEBUG constant (or similar), in your build step you can replace the log statements with a regex:
productionCode = debugCode.replace(/ShouldLog\(((?!LogLevels\.Error|LogLevels\.Warning)[^)]*)\)/g, 'DEBUG');
This would completely remove non-error and non-warning level logging in your code and satisfy (2). You don't really want people peeking at your logs right.. plus better perf! :)
Bonus If you want to get extra funky, you can use the following (at least in Chrome) to get a stack trace for each logging statement in your console. No more 'why did this log get hit'!
window.log = function ()
{
console.groupCollapsed.apply(console, arguments);
var stack = new Error().stack.split('\n');
for(var i = 2; i < stack.length; i ++)
{
// Trim and remove 'at ';
console.log('%c' + stack[i].trim().substring(3), 'padding-left: 10px; color: #777');
}
console.groupEnd();
};
Upvotes: 4