Developing Feather-Weight Webservices with JavaScript

Pixeling & usage tracking

While everything we put together here has been fun and sometimes even utilitarian, there are still business needs unaddressed. Application usage statistics are important. You need to know how your application is being used, or misused, to get an edge on improving it.

Almost all the services here dealt with only one state. They take the client’s configuration, either as a script or URL query string, and use it to create a single static response. The query string version is basically self-tracking because it’s a single state application which logs its calling parameters via the weblogs.

In Inline web tinkering with ColorWheel we have a dynamic service. Even Inline ad box sizing to test layouts counts.

What needs tracking

You have a service that displays a selection menu for sprockets and widgets. You know it’s getting called because you can see GET /myService.js thousands of times in your weblog. You have no clue how the service is being used after that. You don’t know whether sprockets or widgets or neither is being selected by users of the client.

There is a an old fall back which is perfect in this case: pixeling. AKA pixel bugging, bugging, or pixel tracking. It’s ethical if you’re only tracking your own service. Please, do not even consider using such a technique to collect any other information. It’s unethical and probably even illegal depending on what you’re trying to do.

Pixeling

Anyone who has written the smallest web form or the most complex web application knows that web interaction is stateless. The form page you load doesn’t have a memory of the previous page. It must be added programmatically. There is a fancy acronym cooked up lately to put a name on this so the recruiters know what to ask for: REST.

After any client first requests the image, and it is real or else you’ll fill your logs with 404s, they have it cached so it’s not a bandwidth leech. The subsequent requests and the information attached by the query string will meekly line up in the weblogs for shearing at a later date.

You would have a single pixel, 1x1, transparent image (probably PNG or GIF) on your server. To record a state change, ie, an action taken by a user, you would

Why we don’t cover a working version of this

We’d love to say it’s because it’s complicated, code inflating, and wouldn’t contribute to any of our examples. None of that is that true, however. The real reason is laziness and a lack of good reason to use it ourselves.

That said, here is an abbreviated bit of code that could be used to do simple pixel tracking.

Pixel tracking in 10 lines of code

// complicated code that jumps around is best wrapped in objects --
// this function is an object creator, we can now call 'new Tracker()' 
function Tracker () {
  // our base 1x1 transparent image's src
  this.src = 'http://i.example.server/1x1.png';
}

// the call to our tracking, built into the tracking object
Tracker.prototype.trackIt = function ( key, value ) {
  if ( ! ( key && value ) ) return false;
  var pixel = new Image();
  pixel.src = this.src + '?' + escape(key) + '=' + escape(value);
};

// create an instance of our tracking object
var Track = new Tracker();

// call its sole function on some data to catch it in the weblog
Track.trackIt('i','rule');

As basic as it is, it’s pretty solid and extensible. It should probably have an additional prototyped function to build up a queue of data. That way you wouldn’t have to save and log one key=value pair at a time. A full on version should also deal with cookies and session information to help separate out the data later.

To use it, you would need all the above code to instantiate a tracking object somewhere in your service. Then, you can call Track.trackIt('key','value') from anywhere in the following script to record changes. Check Using JS code libraries for a technique to make reusing classes like Tracker() much less painful.

The tracking information is only valuable, of course, if you can get at it. That means parsing the log files for which we recommend Perl, though any number of languages are good for it and C is going to be the fastest which might matter for huge logs with millions and millions of lines.

Don’t forget too that the src of the “image” can be an application URI instead of an image. A mod_perl or PHP application for instance that takes the query string info and inserts it into the DB without needing to parse the weblogs. It would also be the right place to do referrer matching and such to prevent casual data spam or tampering.

« 1x100: Adapting another service, 10x10 · Inline web tinkering with ColorWheel »
Google
 
Web Developing Featherweight Web Services with JavaScript
This is version 0.57b of this manual. It is a beta version with some gaps. We are grateful for feedback.

The code is the manual has not yet been fully tested against Internet Explorer. Bug reports are welcome.
An Elektrum Press Online