Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Javascript Function Calls/Trace at Runtime

As I interact with my AJAX based application at RUNTIME I'd like the console to spit out all the functions it's calling. (so no stack trace, or breakpoints, or profiling or anything)

So for example, let's say I pressed a button on the page. I'd like for it to return all the functions it went through when that happened:

So I'd see in the console something like (when I pressed a button):

1. button1Clicked(); 2.     calculating(); 3.          printingResults(); 

Which basically means that button1Clicked() called calculating() which called printingResults()

Is there a utility, or plugin, browser, or maybe some way in the language to do this? I'm using google chrome, btw.

p.s and NO I do not want to go through each function and add a "console.log("inside function X")" b/c that's too much work

p.p.s as an added bonus I'd like to see the arguments passed into the functions too, but maybe that's pushing it. :>

like image 368
Shai UI Avatar asked Aug 07 '12 20:08

Shai UI


People also ask

What is tracing in JavaScript?

For JavaScript tracing, the tool will add timers in the code to measure the exact performance and memory usage of specific functions. It's a great approach because you can measure the performance and memory usage of individual functions. Low-level code tracing makes the code up to 100 times slower.

Is console log () added to execution stack?

It's a function call. It goes to the call stack.


2 Answers

I can't think of a great way to intercept all function calls globally to insert logging (though there is a decent workaround in the update section below).

Instead, how about only adding logging to functions in a certain namespace that you care about? You can do this with the following setup code:

var functionLogger = {};  functionLogger.log = true;//Set this to false to disable logging   /**  * Gets a function that when called will log information about itself if logging is turned on.  *  * @param func The function to add logging to.  * @param name The name of the function.  *  * @return A function that will perform logging and then call the function.   */ functionLogger.getLoggableFunction = function(func, name) {     return function() {         if (functionLogger.log) {             var logText = name + '(';              for (var i = 0; i < arguments.length; i++) {                 if (i > 0) {                     logText += ', ';                 }                 logText += arguments[i];             }             logText += ');';              console.log(logText);         }          return func.apply(this, arguments);     } };  /**  * After this is called, all direct children of the provided namespace object that are   * functions will log their name as well as the values of the parameters passed in.  *  * @param namespaceObject The object whose child functions you'd like to add logging to.  */ functionLogger.addLoggingToNamespace = function(namespaceObject){     for(var name in namespaceObject){         var potentialFunction = namespaceObject[name];          if(Object.prototype.toString.call(potentialFunction) === '[object Function]'){             namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name);         }     } }; 

Then, for whatever namespaceObject you want to add logging to, you just call:

functionLogger.addLoggingToNamespace(yourNamespaceObject); 

Here's a fiddle to see it in action.

UPDATE
Note that you can call functionLogger.addLoggingToNamespace(window); to add logging to all global functions at the time of the call. Also, if you really want, you can traverse the tree to find any functions and update them accordingly. The one downfall of this method is that it only works on functions that exist at the time. Thus, it's still not the greatest solution, but it's a LOT less work than adding logging statements by hand :)

like image 132
Briguy37 Avatar answered Sep 22 '22 03:09

Briguy37


This is called profiling and Chrome and Firebug have it built in. In Chrome developer Tools, go to the profiles tab and click the record (circle) button. Perform your ajax and after your response, click the record button again to stop. The results of the profiling will appear in the right pane.

Note, this is going to give you everything so if you are using a library like jQuery, the vast majority of the function calls are going to be garbage to you. I've tried this a few times and I find it is much more helpful to do the console.log('inside <method>') thing.

like image 27
Jeff Avatar answered Sep 23 '22 03:09

Jeff