Skip to content

Commit

Permalink
zh-CN:Trans for 'diagnostics-flamegraph.md' (#2103)
Browse files Browse the repository at this point in the history
* zh-CN:Trans for 'diagnostics-flamegraph.md'

1) Trans for Chinese of the file:'diagnostics-flamegraph.md'.
2) Fix some typo errors in the related English version.

* union_to_node.js
  • Loading branch information
Maledong authored and ZYSzys committed Feb 21, 2019
1 parent 8d6627b commit 9088433
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 16 deletions.
31 changes: 15 additions & 16 deletions locale/en/docs/guides/diagnostics-flamegraph.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Flame graphs are a way of visualizing CPU time spent in functions. They can help
You might have heard creating a flame graph for Node.js is difficult, but that's not true (anymore).
Solaris vms are no longer needed for flame graphs!

Flame graphs are generated from `perf` output, which is not a node-specific tool. While it's the most powerful way to visualize CPU time spent, it may have issues with how JavaScript code is optimized in Node 8 and above. See [perf output issues](#perf-output-issues) section below.
Flame graphs are generated from `perf` output, which is not a node-specific tool. While it's the most powerful way to visualize CPU time spent, it may have issues with how JavaScript code is optimized in Node.js 8 and above. See [perf output issues](#perf-output-issues) section below.

### Use a pre-packaged tool

Expand All @@ -32,7 +32,7 @@ Now let's get to work.

1. Install `perf` (usually available through the linux-tools-common package if not already installed)
2. try running `perf` - it might complain about missing kernel modules, install them too
3. run node with perf enabled (see [perf output issues](#perf-output-issues) for tips specific to node versions)
3. run node with perf enabled (see [perf output issues](#perf-output-issues) for tips specific to Node.js versions)
```bash
perf record -e cycles:u -g -- node --perf-basic-prof app.js
```
Expand All @@ -45,26 +45,25 @@ Now open the flame graph file in your favorite browser and watch it burn. It's c

Worth mentioning - if you click an element of a flame graph a zoom-in of its surroundings will get displayed above the graph.

### Using perf to sample a running process
### Using `perf` to sample a running process

This is great for recording flame graph data from an already running process that you don't want to interrupt. Imagine a production process with a hard to reproduce issue.

```
```bash
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.
perf runs for the life of the command you pass to it, whether or not you're actually profiling that command. `sleep 3` ensures that perf runs for 3 seconds.

Why is `-F` (profiling frequency) set to 99? It's a reasonable default. You can adjust if you want.
-F99 tells perf to take 99 samples per second, for more precision increase the value. Lower values should produce less output with less precise results. Precision you need depends on how long your CPU intensive functions really run. IF you're looking for the reason of a noticeable slowdown 99 frames per second should be more than enough.
`-F99` tells perf to take 99 samples per second, for more precision increase the value. Lower values should produce less output with less precise results. Precision you need depends on how long your CPU intensive functions really run. If you're looking for the reason of a noticeable slowdown, 99 frames per second should be more than enough.

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

### Filtering out Node internal functions

### Filtering out Node.js internal functions

Usually you just want to look at the performance of your own calls, so filtering out Node and V8 internal functions can make the graph much easier to read. You can clean up your perf file with:
Usually you just want to look at the performance of your own calls, so filtering out Node.js and V8 internal functions can make the graph much easier to read. You can clean up your perf file with:

```bash
sed -i \
Expand All @@ -73,19 +72,19 @@ sed -i \
perfs.out
```

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.
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.js itself.

### Node's profiling options
### Node.js's profiling options

`--perf-basic-prof-only-functions` and `--perf-basic-prof` are the two that are useful for debugging your JavaScript code. Other options are used for profiling Node itself, which is outside the scope of this guide.
`--perf-basic-prof-only-functions` and `--perf-basic-prof` are the two that are useful for debugging your JavaScript code. Other options are used for profiling Node.js itself, which is outside the scope of this guide.

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

Why do I need them at all?
### 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`.

## perf output issues
## `perf` output issues

### Node.js 8.x V8 pipeline changes

Expand All @@ -101,13 +100,13 @@ For details see:
- https://github.com/nodejs/benchmarking/issues/168
- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961

### Node.js 10+
### Node.js 10+

Node.js 10.x addresses the issue with Turbofan using the`--interpreted-frames-native-stack` flag.
Node.js 10.x addresses the issue with Turbofan using the `--interpreted-frames-native-stack` flag.

Run `node --interpreted-frames-native-stack --perf-basic-prof-only-functions` to get function names in the flame graph regardless of which pipeline V8 used to compile your JavaScript.

### broken labels in flamegraph
### Broken labels in the flame graph

If you're seeing labels looking like this
```
Expand Down
117 changes: 117 additions & 0 deletions locale/zh-cn/docs/guides/diagnostics-flamegraph.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
title: 诊断 - 火焰图
layout: docs.hbs
---

# 火焰图

## 火焰图起什么作用?

“火焰图” 是专门用于分析 CPU 在函数中所消耗的时间。他们可以协助你定位哪些同步方法过于消耗时间。

## 如何创建一个火焰图?

或许你已经听说对于 Node.js,创建火焰图不是非常容易,但是那并不是真的(永远不会)。我们再也不需要 Solaris vms 创建火焰图了!

火焰图通过 `perf` 输出,这并不是一个 node 所指定的工具。即便它是把 CPU 耗时可视化的最佳工具,它仍然存在一些问题 —— 如在 Node.js 8 和之后版本中 JavaScript 编码是如何优化的。欲了解详情可以看[perf 输出的问题](#perf-output-issues)这部分。

### 使用预包装工具

如果你想在本地开始单一输出火焰图,请尝试 [0x](https://www.npmjs.com/package/0x)

如果你想诊断发布的生产环境,请阅读[在生产环境中的 0x](https://github.com/davidmarkclements/0x/blob/master/docs/production-servers.md)

### 用系统工具 `pref` 创建火焰图

本教程的目的在于给你展示如何创建火焰图的具体步骤,这样让你可以对每一步都有掌控。

如果你更好地想理解每一个步骤,请仔细看这些步骤,我们将详细阐述。

现在让我们开始吧:

1. 安装 `perf`(如果你没有安装,那么通常通过 linux-tools-common 安装包进行安装)
2. 尝试运行 `perf` - 或许会告诉你缺少内核模块,请同样安装他们。
3. 启用 pref 并运行 node(具体参考 [perf 输出的问题](#perf-output-issues)以此了解针对不同 Node.js 版本的建议)
```bash
perf record -e cycles:u -g -- node --perf-basic-prof app.js
```
4. 忽略一些警告,除非它告诉你因为缺少必要的安装包而无法运行 pref,你可能会得到一些警告,告诉你不能访问内核模块的样本等。
5. 运行命令 `perf script > perfs.out` 生成稍后你看到的可视化的数据文件。对于一个易读的火焰图而言,[应用清理](#filtering-out-node-internal-functions)是有作用的。
6. 如果没有安装 stackvis,请运行 `npm i -g stackvis`
7. 最后运行 `stackvis perf < perfs.out > flamegraph.htm`

现在你可以使用你最喜爱的浏览器打开火焰图文件,然后观察其燃烧状况。此图是带色编码的,因此你首先应该关注饱和度最深的橘色条。这些最有可能意味着你的 CPU 运行复杂函数消耗的状况。

值得一提的是:如果你点击火焰图的一个元素, 它周围相关的元素将被放大,并将显示在图形的上方。

### 使用 `perf` 对一个运行的进程采样

`pref` 对于一个从已经运行、且不想被随意中断的进程中录制火焰图无疑是相当不错的。设想一下现在你有一个非常难重现问题的生产环境上的进程:

```bash
perf record -F99 -p `pgrep -n node` -g -- sleep 3
```

先停一下,这里 `sleep 3` 是干什么的?它的目的是为了让 pref 持续运行 —— 尽管 `-p` 参数选项是让你指定一个不同的进程 ID(pid),此命令仍然需要在一个进程上执行,并随着它终止。perf 运行的是传递给它的命令的生存期,不管你是否实际分析该命令。`sleep 3` 确保此命令运行 3 秒。

为什么 `-F`(采样频率)要被设置成 99?这是有默认原因的,当然你如果愿意可以任意设置。`-F99` 告诉 pref 每秒采样 99 个样本,目的是为了更精确地提高数值。越是低的数值意味着产出越是低的输出,相伴的也就是越是低精度的结果。你需要的精度取决于你的 CPU 运行多长时间的密集型函数。如果你正在寻找一个明显的减速的原因,那么 99 帧每秒应该是足够的。

当你得到了那 3 秒 pref 生成的记录,请用以上步骤的最后 2 步 处理生成火焰图。

### 过滤掉 Node.js 的内置函数

通常你只希望看到你自定义函数的调用性能如何,因此把 Node.js 和 V8 内置函数过滤掉,可以让你的图变得简单又容易看懂。你可以这样做:

```bash
sed -i \
-e "/( __libc_start| LazyCompile | v8::internal::| Builtin:| Stub:| LoadIC:|\[unknown\]| LoadPolymorphicIC:)/d" \
-e 's/ LazyCompile:[*~]\?/ /' \
perfs.out
```

如果你现在读火焰图,就会觉得它看上去很怪 —— 花费了多数时间的主要函数就像丢了什么一样,你可以尝试不使用过滤参数,那么你也许得到一个罕见的情况下 Node.js 自身的问题。

### Node 的分析选项

`--perf-basic-prof-only-functions``--perf-basic-prof`:此二者函数对你的 JavaScript 调试有帮助,其余选项则用于分析 Node.js 自身,这已经超出了本章的范畴。

`--perf-basic-prof-only-functions`:因为输出少,所以使用此参数选项开销也少。

### 为什么我需要这些参数?

当然,如果没有这些参数的话,你照样可以得到火焰图。不过大部分的条状都将被标记为 `v8::Function::Call`

## `perf` 输出的一些问题

### Node.js 8.x V8 管道上的变化

Node.js 8.x 及以上版本使用了 V8 引擎,采用了新的优化 JavaScript 编译管道模式。这使得一些函数的名字、引用有时候无法被 perf 捕获到(这也被成为“Turbofan”)。

导致的结果也就是在火焰图中你无法正确地得到一些函数名字。

你或许会注意到 `ByteCodeHandler:`,在那儿可以得到你期盼得到的函数名字。

[0x](https://www.npmjs.com/package/0x) 有一些对于此类情况的内置缓解措施。

欲知详情,请了解以下内容:
- https://github.com/nodejs/benchmarking/issues/168
- https://github.com/nodejs/diagnostics/issues/148#issuecomment-369348961

### Node.js 10+

Node.js 10.x 使用 `--interpreted-frames-native-stack` 标志解决了“Turbofan”的问题。

运行 `node --interpreted-frames-native-stack --perf-basic-prof-only-functions`,你就可以在火焰图中得到函数的名字,无论过去 V8 引擎使用那个管道编译你的 JavaScript。

### 火焰图中受损的标签

如果你看到诸如以下的标签:
```
node`_ZN2v88internal11interpreter17BytecodeGenerator15VisitStatementsEPNS0_8ZoneListIPNS0_9StatementEEE
```
这意味着你正在运行的 Linux 的 perf 没有用 demangle 支持方法编译,请以 https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 作为示例参考。


## 示例部分

请通过[火焰图练习](https://github.com/naugtur/node-example-flamegraph)来练习捕获你的火焰图吧!

0 comments on commit 9088433

Please sign in to comment.