How to Perf Nodejs Apps in Container
Contents
In my previous blogs, I’ve shared about how to profile Java applications in various of methods, now I’ll show you how to profile Nodejs apps with perf.
Let’s get started.
Run App with --perf-basic-prof
Argument
First of all, as Nodejs application has a V8 virtual machine and JIT process, perf can’t get the stack traces directly, so we need a solution to achieve this.
Linux perf_events JIT support
In 2009, Linux perf_events added JIT symbol support, so that symbols from language virtual machines like the JVM/V8 could be inspected. It works in the following amazingly simple way:
- Your JIT application must be modified to create a
/tmp/perf-PID.map
file, which is a simple text database containing symbol addresses (in hex), sizes, and symbol names. - That’s it.
perf already looks for the /tmp/perf-PID.map
file, and if it finds it, it uses
it for symbol translations. So only v8 needed to be modified.
v8 –perf-basic-prof support
In November 2013, v8 added perf_events support, enabled using the --perf-basic-prof
option. This made it into node v0.11.13. It works like this:
|
|
This text file is what perf_events reads.
As I run Nodejs applications with pm2 in Docker
container, I’ll --perf-basic-prof
argument like this:
|
|
Perf outside of container
I decide to perf out side of container mainly because of the following 2 reasons:
- additional previlege permissions should be added to container in order to support perf_event_open syscall
- perf inside container may increase a bit of overhead to application namespace
Because we perf outside of container, we need get application’s host PID to perf.
|
|
Here 65875
is our target PID to perf.
|
|
Prepare /tmp/perf-65875.map
file
As we perf outside of container, /tmp/perf-PID.map
file was generated inside
container, we have to copy it out before next process.
|
|
Generate Flame Graph
|
|
We need Gregg’s FlameGraph to generate flame graph.
|
|
Generate
|
|
Now we can get a flame graph like this:
Overall script
You can download FlameGraph
then use this script to get the svg file outside
the container.
|
|
References
Author Wenfeng
LastMod 2019-10-24