ExtraHop offers a lot out of the box, but our infinitely customizable Application Inspection triggers really break open the possibilities, often with very little effort. If you haven't seen the Application Template bundle, go check it out; three lines and you can start bucketizing metrics for your specific apps. When you're ready to start writing your own triggers though, there are a few quick tips that will make sure you're maximizing ExtraHop performance trigger-wise. This mini-series, Trigger Optimization 101, is going to cover several concepts that will set the foundation for you to write your own RUM bundle (or just analyze your data like a pro). I'll also include videos where possible to help you visualize the performance impacts of these changes.
With introductions out of the way, let's get started!
"Just what do you think you're doing, Dave?"
Watch this video (5:24) for a demonstration of this week's topic: exception handling
One of the first things to think about when addressing optimization, is actually error prevention. Hopefully it's not a surprise to anyone that you don't want your triggers throwing exceptions (halting execution because of some unhandled state). The most common type of errors we introduce into our code? Forgetting that a property might be null. Yeah, I'm looking at you HTTP.payload
.
So let's see what this looks like:
var x = null;
// Unhandled exception: TypeError: Cannot call method 'toString' of null
x.toString();
x.toString()
is going to throw a TypeError
because null doesn't have a toString()
method. Folks who are more familiar with coding might be inclined to use Try-Catch blocks to recover from exceptions, but there are very few cases in triggers where you truly need a try-catch structure.
For example:
var x = null;
// Exception handling with try-catch
try {
x.toString();
} catch(err) {
debug('error: ' + err);
return;
}
Why don't we need it? Because we know under what conditions the code snippet will error: if x is some class that doesn't have a toString()
method. Secondly, as you hopefully see in the video, Try-Catch keeps the trigger from halting, but at a heavy price in terms of performance. Instead, try to use defensive programming. In this case, don't assume that what you want is what you'll get, but instead check for error states explicitly and handle them accordingly using built-in logic.
Using defensive programming, the above try-catch example becomes something like:
var x = null;
if (x === null){
debug('error: x === null');
return;
} else {
x.toString();
debug('success');
}
parseInt()
, or typeof to similar effect.
Hopefully you can now see how small changes to your code can have a dramatic effect on trigger performance. If you have a trigger that is executing tens, hundreds, or thousands of times per second, it can be worthwhile to shave a few thousand cycles off each trigger execution. Let us know if there are any topics you'd like to see covered in future posts, or any questions we can help with. We'll be back next time for more trigger optimization tricks!
Related post: How to Build Stellar ExtraHop Dashboards