
Capture, Log, Message, Monitor, Record
Dave's search engine keeps giving a blank result for certain queries. Fortunately, he had previously added some logging commands to see how the query is processed, so he makes the console visible and sets log level to verbose. Entering the query again, he now sees that one of the regular expressions is not matching it as expected.
Instrument your Javascript with log messages. Typically, the page contains a div element especially for logging, and each significant action is appended there, e.g.:
$("log").innerHTML += "User searched for " + query + ".<br/>";
Even this simple implementation offers several benefits over the common alternative: debugging with an alertbox. Most importantly, the log element is a “Popup”: you can easily toggle visibility by dynamically switching CSS properties such as display, or even make it partly transparent. Further, logging is unobtrusive - there's no impact on application flow. Another benefit is that you have a history to consult when something goes wrong - no need to try replicating the problem.
Inspired by libraries such as log4j, Javascript logging libraries provide some sort of filtering. Typically, a message is tagged with a priority level, e.g. "debug" or "info" or "error". You can then choose to see only messages above a certain level.
Logging impacts on performance, not just in DOM manipulation, but in producing the messages themselves. You can also end up with a memory problem unless some measure is taken to clear old messages, e.g. use a buffer to discard old messages.
Instead of logging to a console on the page, some developers output messages to the browser status bar (using window.status), and Firefox developers also have the option of outputting to the browser console. However, this limits portability and requires some configuration.
Another approach gaining traction is to embrace ??? and upload the data to a logging Web Service [21]. This allows permanent storage of the logs, and can also be combined with server-side logs to paint a detailed picture of each interaction. Eric Pascarello, for example, has proposed the technique for usability testing. And log4js supports am XMLHttpRequest-driven logging strategy. The benefits of remote logging must be balanced against concerns for user's privacy and consent.
Most servers are configured to perform logging during production as well as development, so should the browser log too? In the past, the answer was usually no. But Ajax makes the case for browser logging more compelling, for two reasons. Firstly, with more logic in the browser, there's more things that can go wrong and need to be logged. Secondly, ??? makes it possible to accumulate logs on the server, in a completely unobtrusive manner. Still, remote logging does consume application processing time as well as bandwidth, so you'll need to decide if it's worth it, and if so, how much to be logging. In doing so, you'll also need to consider the user's privacy.
In server-side logging systems, log settings are usually altered by applying environment-specific filters - e.g. in development, all messages are shown; whereas in production, only messages at information level above are shown. But a familiar performance problem then arises: even though debug messages aren't being logged, the arguments must nevertheless be constructed, which takes time. A common solution is to include "if-then" statements to check the log level, an unfortunate idiom that obsures the real point of code. Since Javascript is generated by the server, you can do better than that: configure things so that log commands aren't even spit out in the first place. How you do this depends on the server-side environment. For example, a JSP developer could develop a Javascript logging tag whose implementation dynamically inspects the logging configuration.
Corey Johnson's Lumberjack is a Javascript logging framework which supports logging at different levels. There's no setup required, because it creates the logging div itself, so you can immediately issue calls like Logger.info("User logged in."). The console is initially hidden, and you can toggle visibility with Alt-D.
David Miller's fvLogger works similarly to Lumberjack. To use it, you just include a div with optional log level, and make calls like error("No such record.");.
log4js is based more closely on log4j than other frameworks. As well as various log levels, it supports pluggable logging strategies. Logging strategies include: do nothing; log to popup window; upload via “XMLHttpRequest Call”.
Bob Ippolito's Mochikit framework has a similar API to those mentioned above, and also adds features such as log listeners and a configurable message buffer. Interestingly, the standard way to launch the console is with a bookmarklet.
The Basic Ajax Pattern Reader is refactored here to include logging with Lumberjack (Figure 1.100, “Lumberjack”). Lumberjack's logger.js is included, and the code has then been instrumented to include log messages:
Logger.info("Received " + patternNames.length + " pattern names.");
...
Logger.debug("Received summary: " + summaryHTML.substring(0, 100) + "...");
...
Logger.info("Adding " + patternOption.value + " to playlist");
[21] Ajax -
more specifically XMLHttpRequest - has been labelled a technique for
"spying on users" (http://www.devx.com/webdev/Article/28861).
However, techniques for remote logging have been available for a long
time. The main impact of Ajax is to increase rich activity in the
browser, which might create further incentives to log user activity.
See http://www.softwareas.com/spying-on-users-with-xmlhttprequest.