Node.js Diagnostics 101

@naugtur, meet.js summit 2017
## Who is this for?
## I wrote an app ![what](whatcould.jpg)
What I knew about diagnostics in 2012 ```js console.log('AAA', +new Date()) ```
#### Diagnosing common problems ## using tools!
## Problem > High CPU usage or too slow under load
### Need to look for performance improvements ## ⤸ You might want to scale horizontally before investing in optimizations
## Measure ```js console.time('task1') ... console.timeEnd('task1') ``` Useful if you know what the issue could be.
## Measure 2 Node 8.5 shipped with [Performance Timing API](https://nodejs.org/api/perf_hooks.html) ```js const { perf } = require('perf_hooks'); perf.mark('A'); doSomeLongRunningProcess(() => { perf.mark('B'); perf.measure('A to B', 'A', 'B'); const measure = perf.getEntriesByName('A to B')[0]; console.log(measure.duration); // Number of milliseconds between 'A' and 'B' }); ```

profiler

use profiler to track app execution running locally

### text-only profiling ``` node --prof app.js node --prof-process isolate-0x36ccc10-v8.log > result.txt ``` Gives you a summary of where time was spent. Sort of a 1-dimensional flame graph.

flame graph

use flame graphs for best results in production,
with real traffic going on

example
cleaner example
## Problem > App "hangs" for short periods of time or has trouble handling many concurrent clients
### Long synchronous operations block event loop
### First you need to notice Commercial tools for Node all support finding this. There's also the good old `blocked` package ```js blocked(ms => console.log('blocked for '+ms)) ```

Once you know it happens...

Flame graphs or --prof can help if it's significant.

Finding the blocking function
is was hard to do in general.

blocked-at

Thanks to Async Hooks it's finally possible in Node 8

 blockedAt((ms, stack) => console.log(stack))
 at Promise.then ()
  at Immediate.start (/test/cases/promise.js:9:6)
  at runCallback (timers.js:781:20)
  at tryOnImmediate (timers.js:743:5)
  at processImmediate [as _immediateCallback] (timers.js:714:5)
Node 8 starts LTS in October. I will use `blocked-at` in production at Egnyte, and you should try it too.

Digress about async hooks here

## Problem > App eats more and more RAM and memory usage doesn't go down
### It's a memory leak
### Detect Monitor values from `process.memoryUsage()` over time.
### Find source - Create heap snapshots with [heapdump](https://www.npmjs.com/package/heapdump) - Compare heap shanpshots in chromium/chrome
### quick demo It's enough for a [separate talk or workshop](http://naugtur.pl/pres3/memnew/#/) but it's easy to demo in the browser.
## Problem > App crashes with a core dump
### It's an uncaught exception or a crash
## How to diagnose - [`node-report`](https://www.npmjs.com/package/node-report) package may just tell you enough - core dump analysis (remember to enable)
## out-of-memory crash - Memory leak - A bug that correctly allocates over 1.5G - Infinite asynchronous recursion - Recursive promise chain - Lots of streams with fast input and slow output - Accepting uploads to RAM
> I'm aggregating knowledge around tools old and new, building examples, exercises and attending meetings of Diagnostics WG. My ongoing Node diagnostics tutorials work is available [on github](https://github.com/naugtur/node-diagnostics-howtos).

Follow me for workshops on this

@naugtur

naugtur.pl/training/



Subscribe to my newsletter
http://naugtur.pl/news

Q&A or more demos?