JavaScript Log Wrapping
Wrapping console.log
(et al.) in your own function to modify logging behavior.
Why?
You may want a simple way to:
- Enable/disable logging with a flag, e.g.,
DEBUG = true
- Prefix log messages with a common string to identify message origin, e.g.,
>>> [MyClass] Hello!
- Shorter logging syntax, e.g.,
log("Hello!")
- Etc.
We can acheive simple log wrappings by fiddling with the arguments object available in all JavaScript functions, and utilizing Function.prototype.apply.
Demo
For the impatient, a simple demo of these concepts can be found here.
Basic log wraps
The most basic log wrap to exactly mimic console.log
behavior, e.g., to shorten logging syntax, looks like the following, which applies the arguments supplied to log
when calling console.log
.
var log = function(){
console.log.apply(console, arguments);
}
Now you can do simple things like add a DEBUG
flag to enable/disable logging:
var DEBUG=true; // Enable logging
var log = function(){
if(DEBUG){
console.log.apply(console, arguments);
}
}
Modifying Log Messages
You may want to modify the log messages, e.g., add a prefix to all logged messages to determine where the message is coming from, e.g.,
var LOG_PREFIX = "[MyClass]"
var log = function(){
// 1. Convert args to a normal array
var args = Array.prototype.slice.call(arguments);
// 2. Prepend log prefix log string
args.unshift(LOG_PREFIX + " ");
// 3. Pass along arguments to console.log
console.log.apply(console, args);
}
We must convert the arguments
object to a proper array to use Array.unshift
. This is because the arguments
object is only an "Array-like" object, i.e., you can use subscripts, e.g., arguments[0]
, and get its arguments.length
property, but that's about it.
References
- MDN: Function.prototype.apply
- MDN: arguments
- Response to "How to pass all arguments as collection to another function and not as single argument?"
- Response to "Pass arguments to console.log as first class arguments via proxy function"
By Rob McGuire, May 2013
Thanks for the gist!
The only real issue we've still got is that the line number reported in the log output always corresponds to the line where the custom log function ultimately invokes the native
console.log
, instead of the line elsewhere that invokes our customlog
function. If anyone has suggestions for how to remedy that, I'd love to hear them.One of these evenings I'm going to dig further into this post on SO to address the line number issue: