Extending Console.log Without Affecting Log Line
Solution 1:
Yes, it is possible to add information without messing up the originating line numbers of the log invocation. Some of the other answers here came close, but the trick is to have your custom logging method return the modified logger. Below is a simple example that was only moderately tested that uses the context variant.
log = function() {
var context = "My Descriptive Logger Prefix:";
return Function.prototype.bind.call(console.log, console, context);
}();
This can be used with:
log("A log message...");
Here is a jsfiddle: http://jsfiddle.net/qprro98v/
One could get easily get creative and pass the context variable in, and remove the auto-executing parens from the function definition. i.e. log("DEBUG:")("A debug message"), log("INFO:")("Here is some info"), etc.
The only really import part about the function (in regards to line numbers) is that it returns the logger.
Solution 2:
If your use case can deal with a few restrictions, there is a way that this can be made to work. The restrictions are:
The extra log content has to be calculated at bind time; it cannot be time sensitive or depend on the incoming log message in any way.
The extra log content can only be place at the beginning of the log message.
With these restrictions, the following may work for you:
var context = "ALIASED LOG:"
var logalias;
if (console.log.bind === 'undefined') { // IE < 10
logalias = Function.prototype.bind.call(console.log, console, context);
}
else {
logalias = console.log.bind(console, context);
}
logalias('Hello, world!');
Solution 3:
An acceptable solution can be to make your own log-function that returns a console.log
function bound with the log arguments.
log = function() {
// Put your extension code here
var args = Array.prototype.slice.call(arguments);
args.unshift(console);
return Function.prototype.bind.apply(console.log, args);
}
// Note the extra () to call the original console.log
log("Foo", {bar: 1})();
This way the console.log
call will be made from the correct line, and will be displayed nicely in the console, allowing you to click on it and everything.
Solution 4:
It is actually possible in chrome at least. Here is the most relevant. This may vary depending on setup, and how i got the splits was to just log the whole stack, and find the information I needed.
var stack = new Error().stack;
var file = stack.split("\n")[2].split("/")[4].split("?")[0]
var line = stack.split("\n")[2].split(":")[5];
Here is the whole thing, preserving the native object logging.
var orig = console.log
console.log = function(input) {
var isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
if(isChrome){
var stack = new Error().stack;
var file = stack.split("\n")[2].split("/")[4].split("?")[0]
var line = stack.split("\n")[2].split(":")[5];
var append = file + ":" + line;
}
orig.apply(console, [input, append])
}
Solution 5:
You need to call the console.log
with the correct context (console
):
orig.call(console, message);
To complete your function allowing multiple arguments:
var orig = console.log;
console.log = function() {
var msgs = [],
prefix = (window== top ? '[root]' : '[' + window.name + ']');
while(arguments.length) {
msgs.push(prefix + ': ' + [].shift.call(arguments));
}
orig.apply(console, msgs);
};
Demo: http://jsfiddle.net/je2wR/
Remember that you loose the built-in object/array browser in the console when combining objects with strings using the + sign.
Post a Comment for "Extending Console.log Without Affecting Log Line"