Picture

Hi, I'm Boopathi Rajaa.

Hacker, Dancer, Biker, Adventurist

Profiling Node.js applications on OSX

Note: ustack helpers don't work at all on OSX. So the output you get from using dtrace on OSX would be of little help only. Use SmartOS or Illumos based OS to enjoy the advantage of ustack helpers and USDT probes. More about why it doesn't work on OSX is explained nicely here

The happy flow:

  • Make sure all dependencies are installed.
g++ --version #preferably latest
make --version #preferably latest
python --version #Should be 2.6 or 2.7 (as required by node)
tar xvzf node-v0.10.31.tar.gz #replace the filename if necessary
  • This is the most important part. You have to configure node build to be 32-bit and to use dtrace.
./configure --with-dtrace --dest-cpu=ia32
  • Build node with the configured options and install.
make
sudo make install
  • Go have a cup of coffee while make  is taking place.
  • Verify node and npm installation
node --version
npm --version
  • Install stackvis - our flame graph generation tool. Use sudo  if required.
npm install -g stackvis
  • Install your app dependencies. Insert the Nodejs dtrace probes and start your node application
npm install
export DTRACE_DOF_INIT_DEBUG=1
  node app.js > console.log 2> error.log & #you can start it however you like
  • Capture the profile using Dtrace. Dtrace requires additional privileges.
sudo dtrace -n 'profile-97/execname == "node" && arg1/{
  @[jstack(100, 8000)] = count(); } tick-60s { exit(0); }' > stacks.out
  • Run stackvis on the captured stacks.out to generate the flame graph.
stackvis dtrace < stacks.out > stacks.html
  • Open stacks.html from your favourite browser.

Gotchas:

  • If you start your node application with forever or pm2, it might not appear in the pstree as node. So you might have to change - execname == "node"  to pid == 12345  or execname = "pm2"  or something similar.
  • To get SVG, set the output type as flamegraph-svg.
stackvis dtrace flamegraph-svg < stacks.out > stacks.svg
  • I usually run my web app with NODE_ENV=production, 4 processes on a 4 core machine using cluster,  and get profiles under the following conditions - 1. no load, 2. avg load - ( ab -n50 -c3 ), 3. high load ( ab -n200 -c10 ).
  • Found something ? Comment on this post, and I'll add them here.