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:
- Being able to perform other work outside of your log statement that also should not run in production.
- Minimizing file size in production and not shipping logging code.
- Multiple log levels, or different logging groups.
- The ability to turn these logging levels or groups on/off in production.
- Minimizing the amount that you have to type for each log statement.
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();
};