Abstract Your Exception Tracker
This is a blog about the development of Yeller, The Exception Tracker with Answers
Exception Tracking is a crowded market these days. Pretty much every server-side application needs an exception tracking service: staring at log files is dead, you need grouped, detailed information on what went wrong, with deep analysis and good data on when things broke.
Exception trackers usually provide client libraries for your language, and hook into your web framework (or any other global error handler). But sometimes, you want to track that a thing broke, but then handle the error. Such code often looks like this (in Java):
try {
// your code here
} catch (SomewhatExcpectedExceptionThatIWantToLog e) {
yeller.report(e);
}
Now this is a vast improvement over just logging the error to some local file. It gets deduplicated, you can see when an error happened over time and so on. If you use Yeller, you can find out unique data about an error as well - did it only happen on one server? Did it only affect particular users? And a bunch more stuff that you can read about on Yeller’s homepage.
When talking to new customers, I’ve heard the same issue from quite a few of them, as a direct consequence of this pattern:
I have an app with custom $EXCEPTION_TRACKER invocations and ripping them all out really sucks
There’s a relatively trivial, and easy to implement solution here:
Abstract Your Exception Tracker
Your application logic should not know what exception tracker you use. It should just tell somebody that “hey, this exception happened”. Coupling your app code directly to a third party service is a recipe for having to do extra work when you want to switch away, or record internal stats about exceptions (for example).
Exception tracking client libraries usually have a very small interface. It looks something like this (in Java):
public interface ExceptionTracker {
public void report(Throwable error, Map<String, Object> extraData);
}
This one method interface is trivial to extract out, and abstract over. You then get all the usual benefits of abstraction: you can swap out providers, you can mock it trivially during tests, you can try out new providers alongside old ones and so on.
The Tradeoffs
A recurring theme in Yeller’s blog now, is covering the tradeoffs of various engineering decisions. This decision is nearly all wins, for nearly all cases. It takes maybe 20 seconds to setup, and brings you a heap of benefits.
The only real tradeoff is when you’re absolutely sprinting for a new project - say you’re building a thing for the Rails Rumble, or the Clojure Cup (which Yeller is sponsoring this year) or something like that. Then, I’d typically say that this abstraction is likely a mistake (but if you were going to continue building your app after the end of the time-limited period, then I’d rip out direct calls to an exception tracker and use the method detailed here).
This is a blog about the development of Yeller, the Exception Tracker with Answers.