How to get Javascript Function Calls/Trace at Runtime

前端 未结 8 1876
天命终不由人
天命终不由人 2020-12-23 13:56

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 pr

相关标签:
8条回答
  • 2020-12-23 14:34

    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.

    0 讨论(0)
  • 2020-12-23 14:40

    I just found out that you could do that with a console.trace()

    0 讨论(0)
  • 2020-12-23 14:43

    A variation on Briguy37's solution, I wrote one that accepts a function to call before each method. It also works with ECMAScript 6 classes, where methods are not enumerated by for...in. I'm using it to modify Object prototypes, to add logging to all new instances of my object.

    function inject(obj, beforeFn) {
        for (let propName of Object.getOwnPropertyNames(obj)) {
            let prop = obj[propName];
            if (Object.prototype.toString.call(prop) === '[object Function]') {
                obj[propName] = (function(fnName) {
                    return function() {
                        beforeFn.call(this, fnName, arguments);
                        return prop.apply(this, arguments);
                    }
                })(propName);
            }
        }
    }
    
    function logFnCall(name, args) {
        let s = name + '(';
        for (let i = 0; i < args.length; i++) {
            if (i > 0)
                s += ', ';
            s += String(args[i]);
        }
        s += ')';
        console.log(s);
    }
    
    inject(Foo.prototype, logFnCall);
    
    0 讨论(0)
  • 2020-12-23 14:46

    I've used @Briguy37's solution with an improvement. In my case, I did not want to trace functions from some libraries, so I added some code to exclude them. Here is how it is used:

    • First, include the definition of the functions you don't want to trace;
    • excludeLoggingToNamespace to list the functions defined up to now and exclude them;
    • Include the definition of the functions you want to trace;
    • Call addLoggingToNamespace to add the logging capability to the functions defined in the above step.

    Example:

    <script src="js/someLibrary.js"></script>
    <script>
        functionLogger.excludeLoggingToNamespace(window);
    </script>
    <script src="js/codeIWantToTraceHere.js"></script>
    <script>
        functionLogger.addLoggingToNamespace(window);
    </script>
    

    Here is the code I added to @Briguy37's solution:

    var excludedFunctions = {};
    
            functionLogger.excludeLoggingToNamespace = function(namespaceObject){
                for(var name in namespaceObject){
                    var potentialFunction = namespaceObject[name];
    
                    if(Object.prototype.toString.call(potentialFunction) === '[object Function]') {
                        excludedFunctions[name] = name;
                    }
                }
            }; 
    

    And I had to modify @Briguy37's addLoggingToNamespace method to take into accound the excludedFunctions hash:

    functionLogger.addLoggingToNamespace = function(namespaceObject){
        for(var name in namespaceObject){
            var potentialFunction = namespaceObject[name];
    
            if(Object.prototype.toString.call(potentialFunction) === '[object Function]' && 
               !excludedFunctions[name]) {
                namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name);
            }
        }
    };    
    
    0 讨论(0)
  • 2020-12-23 14:46

    Let me throw a third (also admittedly somewhat imperfect) solution into the ring.

    Note that all other answers offer two kinds of solutions:

    1. Manually patch your JS functions in run-time, and log them to console
      • Yes it can get the job done, but will be useless once your project grows to a certain size. It does not give you sufficient controlability, unless you keep spending time on keeping on deleloping this feature.
    2. Jeff proposes using a profiler for debugging purposes
      • Not very helpful, as the profiler views (at least for now) are designed to help you analyze performance, not the call graph; does not work well, unless you spend a lot of time training yourself to getting used to the counter-productive user interface.

    That is why I wrote Dbux, a work in progress, which currently only works as a VSCode addon with some limitations. However, it is an omniscient debugger with dynamic execution analysis tools, code annotations and a full-blown dynamic call graph visualization tool, aimed at helping developers with Program Comprehension and Debugging:

    Links:

    • Dbux VSCode Extension (with a lot of documentation and some pictures)
    • Dbux Github Repo
    • Introduction Video with 2 Examples
    0 讨论(0)
  • 2020-12-23 14:50

    Maybe you can have JavaScript do some of the work of adding console.log for you:

    Adding console.log to every function automatically

    Also this blog by Paul Irish might help:

    http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/

    It includes a link to some JavaScript specifically targeted at logging arguments:

    http://pastie.org/1033665

    0 讨论(0)
提交回复
热议问题