Tracing Lambda with X-Ray, Node.js and Webpack
How to use webpack to enable captured x-ray tracing without changing your code.
Exploding your monolith into a thousand moving serverless functions is a surprisingly good way to get agile, deliver new features quickly and even improve your scalability. Like all great architectures, however, it doesn’t come without its challenges and disadvantages.
If you want to find out what the problems are with a technology, all you need do is look at the commercial ecosystem that’s grown up around it. There’s a reason why you can’t throw a rock at a serverless meetup without hitting someone offering a tool for monitoring serverless applications. [ed. I do not condone throwing stones at serverless events, especially because I’ll be talking at one next week!] And that’s because tracing an action as it percolates through the swarm is a difficult task if all you’ve got is cloudwatch.
To help ease the burden AWS released X-Ray, which allows you to trace and measure the duration of all the downstream calls (even branching ones) of a service in a typically ugly, but perfectly serviceable, way (as is traditional with all AWS tooling…).
Despite what you might have thought, however, getting any meaningful information is not as simple as checking the ‘Enable active tracing’ box on the lambda dashboard. This is because you need to instrument your lambda before you can see anything but the time it took to start and run.
Luckily AWS provides a way to automatically annotate any inter-AWS call using the aws-xray-sdk. With the incredibly handy
captureAWS transformer, you can get an instance of the
aws-sdk that does all the magic required to measure calls across services (and even other lambdas):
The observant amongst you may have noticed, however, that instrumenting your application requires a code change. And for the sort of large project you would actually want get some insights into, you’ll be looking at a large number of changes. In my experience tracing is normally the result of a precision (and often temporary) investigation, so having to make, commit, build (and even maintain) instrumentation code changes can be a real burden.
Luckily most big node.js projects are built with webpack! And when it comes to automating a bit of indirection in your code, you can’t get better than webpack. To conditionally swap out out
aws-sdk with a traced version we need to use webpack’s NormalModuleReplacementPlugin:
webpack.config.js above replaces imports of
aws-sdk with a local
bootstrap-xray.js (which returns a pre-captured version of the aws sdk) if either the
COMPILE_WITH_XRAY environmental variable was set, or if you’re switched on tracing using the excellent serverless-plugin-tracing plugin for the serverless framework.