4

I need to take a load of Javascript and instrument it automatically: specifically I want to log every call to a function, and provide a list of arguments that the function was invoked with.

I have a half-baked way of doing this with Python : using 're' to match 'function' keywords - but it's really quite primitive (doesn't deal with comments and so on).

I'm no expert (very far from it) with ANTLR: but how easy could I leverage a already built Javascript Parser to perform this ? (Can we 'hook' out to standard java to dynamically create the code I need at the right point?)

BTW: the actually logging will (probably) be done with log4javascript; but I might also just use 'alerts' - the hard bit is getting the code-injection working....

So for example, I need to turn something like:

function foo(bar) {
...
}

into:

function foo(bar) {
alert("<scriptname.js>: foo was called with arguments: [bar="+bar+"]");
...
}
monojohnny
  • 5,894
  • 16
  • 59
  • 83
  • Can you elaborate on the reason you can't just wrap the target functions in JavaScript? That is, wrap the function in another function that logs the message and the params and then calls the target function? – Pointy Feb 28 '12 at 17:35
  • I guess I could do that (I have access to the code which _calls_ the library); but I'm not sure that makes the task easier in practice - I would still have to parse the javascript to create a 'mirror' version of the js code this way I think ? Also, I'm not sure how to deal with functions that call within the existing source; I would have to make sure those calls get 'routed' to the 'mirrors'....unless I have misunderstood your idea.? – monojohnny Mar 05 '12 at 16:30

2 Answers2

5

Regular expressions won't do it. If you want to instrument code reliably, you need reliable parsers and trustworthy mechanisms for inserting the instrumentation.

See my paper on building test coverage tools by instrumenting code. It describes how to instrument code in very general way, using source-to-source program transformations, to do the kinds of things such as what you want to do.

My company builds a line of robust test coverage tools this way.

You can do this kind of thing with ANTLR but it is a lot clumsier; you have write the transformations procedurally, and then you have to regenerate the source code from the parse tree. That's a lot harder than it looks.

Community
  • 1
  • 1
Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
3

You could instrument your JavaScript code with Google's Web Tracing Framework. It provides instrumenting functions.

There is also Violin, which is an experiment in instrumenting JavaScript applications.

As you want to know the parameters with which your functions have been called, I can suggest Theseus to you. It provides an asynchronous call tree with function invocations and arguments.

Here is an example on how to capture your arguments with Theseus:

function foo(bar) {
  theseus.traceEnter("function-id", "...");
  try {
    // original code
  } catch (error) {
    theseus.traceException("function-id", error);
  } finally {
    theseus.traceExit("function-id", "...");
  }
}

Your arguments get passed into traceEnter and traceExit to be saved. You can read more about it on Instrumenting JavaScript in JavaScript.

Benny Code
  • 51,456
  • 28
  • 233
  • 198