Skip to content

Commit

Permalink
some editing around flame graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
naugtur committed Mar 23, 2017
1 parent fd16759 commit 280db51
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
----
### Goal

This repo is for putting all the intricate bits of knowledge about diagnosing what happens to node applications performance and memory etc. in one place.
The purpose of this repo is to collect all the intricate bits of knowledge about diagnosing what happens to node applications' performance, memory and production runtime.

- short documents
- link only to resources that should stay up
- make recognizing what's outdated easy
- make it useful as notes for someone who knows it already but needs details to be able to teach others without preparation

---


- Why does it focus on tools for Linux?
- Because people tend not to run web applications in production on Mac.
22 changes: 12 additions & 10 deletions flame-graphs.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# Flame graphs

## What's flame graph useful for?
## What's a flame graph useful for?

Flame graphs are a way of visualizing CPU time spent in functions. They will help you pin down where you spend too much time doing synchronous operations.

## How to flame graph

no more Solaris vms for flame graphs on linux!

1. install lldb in your system (from apt)
1. install lldb in your system (eg. with apt-get)
1. install llnode according to readme [llnode notes](llnode.md)
1. install linux-tools-common (from apt)
1. try running `perf` - it might complain about missing modules, install them too
1. install linux-tools-common (eg. with apt-get)
1. try running `perf` - it might complain about missing kernel modules, install them too
1. install stackvis `npm i -g stackvis`
1. run node with perf enabled `perf record -e cycles:u -g -- node --perf-basic-prof app.js`
1. disregard warnings unless they're saying you can't run perf due to missing packages; you will get some warnings about not being able to access kernel module samples which you're not after anyway.
1. run `perf script`, but pipe it through some cleanup: `perf script | egrep -v "( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)" | sed 's/ LazyCompile:[*~]\?/ /' > perfs.out`
1. `stackvis perf < perfs.out > flamegraph.htm`
1. run `perf script`, but pipe it through some cleanup: `perf script | egrep -v "( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)" | sed 's/ LazyCompile:[*~]\?/ /' > perfs.out` [explanation](#about-perf-script-filtering)
1. run `stackvis perf < perfs.out > flamegraph.htm`

and watch it burn :)

Expand All @@ -28,23 +28,25 @@ perf record -F99 -p `pgrep -n node` -g -- sleep 3

Wait, what is that sleep 3 for? It's there to keep the perf running - despite `-p` option pointing to a different pid, the command needs to be executed on a process and end with it. That's just how perf works.

Why is `-F` (profiling frequency) set to 99? I honestly don't know, Netflix guys used that value. Results look good.
Why is `-F` (profiling frequency) set to 99? I honestly don't know, Netflix guys used that value. Results look good. You can adjust if you want.

After you get that 3 second perf record, proceed with generating the flame graph with last two steps from above.

### About `perf script` filtering

The long line of greps and seds after `perf script` call is there to remove some V8 and node internals so that it's easier for you to focus on your JavaScript calls. If you read your flame graph and it seems odd, as if something is missing in the key function taking up most time, try generating one without the filters.
The long line of greps and seds after `perf script` call is there to remove some V8 and node internals so that it's easier for you to focus on your JavaScript calls. These are only important if you are looking for an issue with Node internals.

If you read your flame graph and it seems odd, as if something is missing in the key function taking up most time, try generating your flame graph without the filters - maybe you got a rare case of an issue with Node itself.

### Node's profiling options

`--perf-basic-prof-only-functions` and `--perf-basic-prof` seem like the only two you might be initially interested in for debugging your JavaScript code. I'm not even going to link to more advanced stuff.
`--perf-basic-prof-only-functions` and `--perf-basic-prof` seem like the only two you might be initially interested in for debugging your JavaScript code. I'm not even going to link to more advanced stuff here. Profiling Node itself is outside the scope of this howto.

`--perf-basic-prof-only-functions` produces less content, so it's the option with least overhead.

Why do I need them at all?

Well, without these options you'll still get a flame graph, but with most bars labeled `v8::Function::Call`.
Well, without these options you'll still get a flame graph, but with most bars labeled `v8::Function::Call`.

## Examples

Expand Down
2 changes: 1 addition & 1 deletion samples/flame-graph-exercise/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ Generate a flame graph, identify the function in your code that performs the lon
## Task 2
Now for something more realistic.

Start the app, open http://localhost:8080/ to simulate traffic, run a short perf on a running process and generate a flame graph.
Start the app, open http://localhost:8080/ to simulate traffic, run a short perf on the running process and generate a flame graph. See if you would identify the function under real traffic. Try with shorter sleep and lower profiling frequency too.

0 comments on commit 280db51

Please sign in to comment.