How to get the console.log content as string in JavaScript - javascript

I'm trying to get the console.log as string in pure JavaScript.
My input is a script, which I'm not familiar with, and I want to collect all the messages in the console.log into a string.
For example:
function doSomething(){
console.log("start");
console.log("end");
var consoleLog = getConsoleLog();
return consoleLog;
}
function getConsoleLog(){
// How to implement this?
}
alert(doSomething());
JSFiddle link
Note that I do not need to alert the log - this is just a simple example of testing the functionality. I'll have to do some operations on the log's content.

You could overwrite console.log method before using it:
var logBackup = console.log;
var logMessages = [];
console.log = function() {
logMessages.push.apply(logMessages, arguments);
logBackup.apply(console, arguments);
};
Using apply and arguments preserves the correct console.log behaviour, i.e. you can add multiple log messages with a single call.
It will push all new console.log messages to logMessages array.

for security issues, there is no api to read the history of console.log().

Related

Is there a function that allows you to listen for console logs in javascript?

I've tried searching it up with multiple different wordings and on multiple websites with no answer, is it possible, is it not, and if so, how? I need to be able to get code to run when anythign is logged to the console and get what that thing was.
You can override console.log's default behavior:
var log = console.log;
var logs = []
console.log = function(e) {
log.apply(console, [].slice.call(arguments));
logs.push(e) //custom code
};
console.log("Hello World!")
console.log('Printed logs:', logs)
Save the original console
var log = console.log;
Monkey patch it i.e. modify it when run and all at runtime
//use the log instance and 'apply()' method to apply to inherit it
//we pass in a date for each call of console.log() when using the original ( log() )
log.apply(console, [(new Date().toString())].concat([].slice.call(arguments)) ); };
Now everytime we call - log() - we are calling the original
//to test it do this
log('test','this is the original console.log());
This is the patched version
console.log("This is the Monkey Patched console.log()!", "More text...");

TypeError: Function.prototype.call called on incompatible undefined [duplicate]

I noticed something curious earlier today. I can't seem to store a reference to the call property of a function, then execute it. Example:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall(console, 'This does not');
To me, this seems like perfectly legal Javascript, but the second invocation always gives me the error that undefined is not a function. Feel free to play around with it here, you'll get the same results.
So why does Javascript prevent me from calling call in this manner?
EDIT: I finally got it straight in my head after reading SimpleJ's answer. So I'm going to update this with how you can get the above to work:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall.call(console.log, console, 'This works now too');
The problem was that console.log was receiving the proper this value, but console.log.call wasn't given a proper this value. So as you can see, I basically had to execute console.log.call.call. Obviously you'd never really use code like this, I was just curious.
You need to keep the binding to console. Try this:
var logCall = console.log.call.bind(console.log);
// example: logCall(console, "foobar");
or
var log = console.log.bind(console);
// example: log("foobar");
For a bound reference to log.
Edit:
jsfiddle: http://jsfiddle.net/67mfQ/2/
This is my favorite code in JavaScript:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind);
var callable = bindable(call);
You can use the bindable function to grab a reference to f.bind. Similarly you can use the callable function to grab a reference to f.call as follows:
var log = callable(console.log, console);
Now all you need to do is call the log function like any other function:
log("Hello World!");
That's all folks.

Monitor JavaScript output, such as console.log()

I've been hunting around Google and various JavaScript websites, but I've yet to find an answer for this. Is there any way that I could use JavaScript/JQuery to monitor events such as console.log()?
For example, I'd like to trigger an even when a separate, cumbersome-to-deal with script calls console.log('foo'); When using any web inspector with a JavaScript console, it's easy to see foo pop up when the script logs it, but is there a way I can hook that event with a different script?
Code borrowed from Can I extend the console object (for rerouting the logging) in javascript?:
(function() {
var exLog = console.log;
console.log = function(msg) {
exLog.apply(console, arguments);
alert(msg);
}
})()
This should allow you to do just about anything when console.log() has been executed, as long as this code runs before console.log() is executed.
While you cannot extend console, you can wrap each of it's methods. The code below intercepts every logging method and records each call in a variable called log.
var actualConsole = window.console;
var c = window.console = {};
var log={};
for (var m in actualConsole){
if (typeof console[m] ==='object'){
c[m]=console[m];
}else if (typeof actualConsole[m] ==='function'){
c[m]=function () {
var args = Array.prototype.slice.call(arguments);
log[this]=log[this]||[];
log[this].push(args);
actualConsole[this].apply(actualConsole,args);
}.bind(m);
}// else - nothing else expected
}
console.log('log',1);
console.log('log',2);
console.error('error',1);
console.warn('warn',1);
actualConsole.log('log:',log);
Log looks like:
{"log":[["log",1],["log",2]],"error":[["error",1]],"warn":[["warn",1]]}

Store reference to `call` function

I noticed something curious earlier today. I can't seem to store a reference to the call property of a function, then execute it. Example:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall(console, 'This does not');
To me, this seems like perfectly legal Javascript, but the second invocation always gives me the error that undefined is not a function. Feel free to play around with it here, you'll get the same results.
So why does Javascript prevent me from calling call in this manner?
EDIT: I finally got it straight in my head after reading SimpleJ's answer. So I'm going to update this with how you can get the above to work:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall.call(console.log, console, 'This works now too');
The problem was that console.log was receiving the proper this value, but console.log.call wasn't given a proper this value. So as you can see, I basically had to execute console.log.call.call. Obviously you'd never really use code like this, I was just curious.
You need to keep the binding to console. Try this:
var logCall = console.log.call.bind(console.log);
// example: logCall(console, "foobar");
or
var log = console.log.bind(console);
// example: log("foobar");
For a bound reference to log.
Edit:
jsfiddle: http://jsfiddle.net/67mfQ/2/
This is my favorite code in JavaScript:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind);
var callable = bindable(call);
You can use the bindable function to grab a reference to f.bind. Similarly you can use the callable function to grab a reference to f.call as follows:
var log = callable(console.log, console);
Now all you need to do is call the log function like any other function:
log("Hello World!");
That's all folks.

Put a value in webkit console from console.log into a variable

If there is an output in the chrome/safari webkit inspector containing an object that prints out such as:
Only much more complicated with loads of nested objects (which is why a copy/paste wont do)
Is there a way to put this in a variable to inspect in further and process it after its been printed on the console (its printed via console.log), just only after its already in the console?
$_ will give you last output of console. So in console you can assign in to a variable.
Note that you can do this only in console and not from your own code.
Here's a way to do it without wrapping console.log in a custom log function:
var justLogged;
var oldLog = console.log;
console.log = function () {
oldLog.apply(console, arguments);
justLogged = arguments;
};
console.log('test');
// if necessary, restore console.log to its original behavior when you're finished with it
console.log = oldLog;
The value of justLogged will be ['test'], since you just logged it.
If you're looking to get the last output, do as Mohsen suggests.
If you're trying to get the last output of console.log, your best bet is a wrapper function. This can (1) do what you want (2) easily be disabled in production, which is helpful on old IE and hides debug messages.
var log = (function() {
var lastOutput;
var fn = function() {
lastOutput = arguments[0]; // save the last argument
console.log.apply(console, arguments); // defer to console.log
};
fn.last = function() {
return lastOutput;
};
return fn;
})();
log("abc123");
log.last(); // => "abc123"

Categories