<< A new job means a new keyboard | Home | Good code vs bad code >>

How is my website doing?

How to monitor JavaScript exceptions

It's a question that everyone with a website should have in mind all the time, and often a question that is pretty hard to answer. I mean, how do you know how your website is doing? You can open it up, but that says nothing of what it looks like to your users.

For one, you can look into your server logs. Errors are usually logged in one or more files and this is a good place to start when checking the health of your website. That takes care of the server side of things. What about the front? How can you know if in that particular browser your website is not blowing up in JavaScript errors?

Well, fortunately, you can trap JavaScript errors. All errors on a page. And then, you can call a specific URL on your server in order to log those errors. You may want to log the date, the User-Agent string along with it.

So, how does that work? Well, put these few lines of JavaScript on top of your pages:

<script> window.onerror = function(message, url, lineNumber) { var m = "M: " + message + "\r\nSRC: " + url + ":" + lineNumber + "\r\nUA: " + navigator.userAgent + "\r\nHREF: " + location.href; var i = new Image(); i.src = "/myUrlToLogJSErrors?message=" + encodeURIComponent(m); return true; }; </script>

Of course, you will have to write something on your server that takes a message and log it.

Now, if we want to play nicely with the browsers, your URL that logs should return something valid. Something valid, in this case, is an image. You have several options here:

  • You can create a small GIF with the Gimp and serve that file. It is very inefficient as it implies going to the hard disk drive, reading a file, etc... Remember this image isn't going to be displayed anyways.
  • You can dynamically generate a GIF with Java or whatever language you have on the server. This is even worse as these libraries (generating images) are very heavyweight.
  • You can hardcode your small image as an array of bytes in your code and serve that. This is my preferred way of doing it.
Now that it's all set, what is the smallest possible valid GIF file? 26 bytes apparently, according to this website. Here is what it could look like on the server side in Java:
public class MyLoggingServlet extends HttpServlet { private static byte[] tinyGIF = {(byte)71,(byte)73,(byte)70,(byte)56,(byte)57,(byte)97,(byte)1,(byte)0,(byte)1,(byte)0,(byte)0,(byte)-1,(byte)0,(byte)44,(byte)0,(byte)0,(byte)0,(byte)0,(byte)1,(byte)0,(byte)1,(byte)0,(byte)0,(byte)2,(byte)0,(byte)59,(byte)0,(byte)0,(byte)0,(byte)0 }; public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { String m = String.valueOf(req.getParameter("message")); System.out.println(new Date()); System.out.println(m); res.setContentType("image/gif"); res.getOutputStream().write(tinyGIF); } }
Of course, instead of using System.out.println you should use your preferred logging mechanism such as log4j