tracer是一个高级的性能分析和诊断工具,但是不要让这名词唬住你,如果你使用过 strace 和 tcpdump,其实你就已经使用过跟踪器了。系统跟踪器可以获取更多的系统调用和数据包。它们通常能跟踪任意的内核和应用程序。

有太多的 Linux 跟踪器可以选择。每一种都有其官方的(或非官方的)的卡通的独角兽吉祥物,足够撑起一台”儿童剧”了。

那么我们应该使用哪个跟踪器呢?

可分为两类:大多数人和性能/内核工程师。

对于大多数人

大多数人 (开发者,系统管理员,开发管理者,运维人员,评测人员,等等) 不关心系统追踪器的细节。下面是对于追踪器你应该知道和做的:

1. 使用 perf_events 分析 CPU 性能

使用 perf_events 做 CPU 性能分析。性能指标可以使用 flame graph 等工具做可视化。

git clone --depth 1 https://github.com/brendangregg/FlameGraph
perf record -F 99 -a -g -- sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > perf.svg

Linux perf_events (又称 “perf”,同命令名) 是 Linux 用户的官方跟踪器和性能分析器。内置于内核代码,有很好维护(近来获得快速增强),通常通过 linux-tools-common 软件包安装。

perf 有很多功能,如果只能推荐一个,我选择 CPU 性能分析。尽管这只是采样,而不是从技术上追踪事件。最难的部分是获取完整的栈和信息,我为 java 和 node.js 做的一个演讲 Linux Profiling at Netflix 中已经说过这个问题。

2. 了解其他的跟踪器

正如我一个朋友说的:“你不需要知道如何操作 X 射线机器,但是一旦你吞了一枚硬币,你得知道这得去做 X 射线”,你应该了解各种跟踪器都能做什么,这样就能在你工作中真正需要跟踪器的时候,你既可以选择稍后学习使用,也可以雇相应的人来完成。

简短来说:几乎所有的东西都可以使用跟踪器来进行分析和跟踪。如,文件系统内部、TCP/IP 过程、设备驱动、应用程序内部。可以看一下我的个人网站上关于 ftrace 的文章,还有我写的关于 perf_events 文档介绍,可以做为一个追踪(或者性能分析)的例子。

3. 寻求前端支持工具

如果你正想买一个能支持跟踪 Linux 的性能分析工具(有许多卖这类工具的公司)。想像一下,只需要直接点击一下界面就能“洞察”整个系统内核,包括隐藏的不同堆栈位置的热图,我在 Monitorama talk 中介绍了一个这样带图形界面的工具。

我开源了一些我自己开发的前端工具,尽管只是命令行界面而不是图形界面。这些工具也会让人们更加快速容易的使用跟踪器。比如下面的例子,用我的 perf_tool,跟踪一个新进程:

# ./execsnoop
Tracing exec()s. Ctrl-C to end.
   PID   PPID ARGS
 22898  22004 man ls
 22905  22898 preconv -e UTF-8
 22908  22898 pager -s
 22907  22898 nroff -mandoc -rLL=164n -rLT=164n -Tutf8
[...]

在 Netflix 上,我们创建了一个 Vector,一个分析工具的实例,同时也是 Linux 上的跟踪器的最终前端。

对于性能/内核工程师

我们的工作变的越来越困难,很多的人会问我们怎么样去追踪,哪种跟踪器可以用!为了正确理解一个跟踪器,你经常需要花上至少100个小时才能做到。理解所有的 linux 跟踪器去做出理性的选择是一个浩大的工程。(我可能是唯一一个快做到这件事情的人)

这里是我的建议,可以二选其一:

A) 选中一个全能的跟踪器,并且使它标准化,这将涉及花费大量的时间去弄清楚它在测试环境中的细微差别和安全性。我现在推荐 SystemTap 的最新版本(可以从源代码构建)。我知道有些公司已经选用 LTTng,而且他们用的很好,尽管它不是非常的强大(虽然它更安全)。如果 Sysdig 可以增加追踪点tracepoint或者 kprobes,可以做为另一个候选。

B) 遵循我上面提供的流程图,它将意味着尽可能更多的使用 ftrace 或者 perf_event, 并整合 eBPF,之后其他的跟踪器像 SystemTap/LTTng 会去填补剩下的空白。 这就是我目前在 Netflix 做的工作。

对跟踪器的评价

1. ftrace

我喜欢用 ftrace,它是内核 hacker 的首选,内置于系统内核,可以使用跟踪点(静态检查点),能调用内核 kprobes 和 uprobes 调试工具。并且提供几个这样的功能:带可选过滤器和参数的事件追踪功能;在内核中进行统计的事件计数和定时功能;还有函数流程遍历的功能。可以看一下内核代码中 ftrace.txt 例子了解一下。ftrace 由 /sys 控制,仅支持单一的 root 用户使用(但是你可以通过缓冲区实例改成支持多用户)。某些时候 ftrace 的操作界面非常繁琐,但是的确非常“hack”,而且它有前端界面。ftace 的主要作者 Steven Rostedt 创建了 trace-cmd 命令工具,而我创建了 perf 的工具集。我对这个工具最大的不满就是它不可编程。举例来说,你不能保存和获取时间戳,不能计算延迟,不能把这些计算结果保存成直方图的形式。你需要转储事件至用户层,并且花一些时间去处理结果。ftrace 可以通过 eBPF 变成可编程的。

2. perf_events

perf_events 是 Linux 用户的主要跟踪工具,它内置在内核源码中,通常通过 linux-tools-commom 安装。也称为“perf”,即其前端工具名称,它通常用来跟踪和转储信息到一个叫做 perf.data 的文件中,perf.data 文件相当于一个动态的缓冲区,用来保存之后需要处理的结果。ftrace 能做到的,perf_events 大都也可以做到,perf-events 不能做函数流程遍历,少了一点儿“hack”劲儿(但是对于安全/错误检查有更好的支持)。它可以进行 CPU 分析和性能统计,用户级堆栈解析,也可以使用对于跟踪每行局部变量产生的调试信息。它也支持多用户并发操作。和 ftrace 一样也不支持可编程。如果要我只推荐一款跟踪器,那一定是 perf 了。它能解决众多问题,并且它相对较安全。

3. eBPF

extended Berkeley Packet Filter(eBPF)是一个可以在事件上运行程序的高效内核虚拟机(JIT)。它可能最终会提供 ftrace 和 perf_events 的内核编程,并强化其他的跟踪器。这是 Alexei Starovoitov 目前正在开发的,还没有完全集成,但是从4.1开始已经对一些优秀的工具有足够的内核支持了,如块设备 I/O 的延迟热图。可参考其主要作者 Alexei Starovoitov 的 BPF slideseBPF samples

4. SystemTap

SystemTap 是最强大的跟踪器。它能做所有事情,如概要分析,跟踪点,探针,uprobes(来自SystemTap),USDT 和内核编程等。它将程序编译为内核模块,然后加载,这是一种获取安全的巧妙做法。它也是从 tree 发展而来,过去有很多问题(崩溃或冻结)。很多不是 SystemTap 本身的错——它常常是第一个使用某个内核追踪功能,也是第一个碰到 bug 的。SystemTap 的最新版本好多了(必须由源代码编译),但是很多人仍然会被早期版本吓到。如果你想用它,可先在测试环境中使用,并与 irc.freenode.net 上 的 #systemtap 开发人员交流。(Netflix 有容错机制,我们已经使用了 SystemTap,但是可能我们考虑的安全方面的问题比你们少。)我最大的不满是,它似乎认为你应该有内核 debug 信息,但是经常没有。实际上没有它也能做很多事情,但是缺少文档和例子(我必须自己全靠自己开始学习)。

5. LTTng

LTTng 优化了事件采集,这比其他跟踪器做得好,它也支持几种事件类型,包括 USTD。它从 tree 发展而来,它的核心很简单:通过一组小规模的固定指令集将事件写入追踪缓冲区,这种方式使它安全、快速,缺点是它没有内核编码的简单途径。我一直听说这不是一个大问题,因为尽管需要后期处理,它也已经优化到可以充分的度量。此外,它还首创了一个不同的分析技术,对所有关注事件的更多黑盒记录将能够稍后以 GUI 的方式进行研究。我关心的是前期没有考虑到要录制的事件缺失问题如何解决,但我真正要做的是花更多时间来看它在实践中用的怎么样。这是我花的时间最少的一个跟踪器(没有什么特殊原因)。

6. Ktap

ktap 是一款前景很好的跟踪器,它使用内核中的 lua 虚拟机处理,在没有调试信息的情况下在嵌入式设备上运行的很好。这让它得到了关注,并在有一段时间似乎超过了 Linux 上所有的追踪器。然后 eBPF 开始集成到内核了,而 ktap 的集成会在可以使用 eBPF 替代它自己的虚拟机后才开始。因为 eBPF 仍将持续集成几个月,ktap 开发者要继续等上一段时间。我希望今年晚些时候它能重新开发。

7. dtrace4linux

dtrace4linux 主要是 Paul Fox 一个人在业余时间完成的,它是 Sun DTrace 的 Linux 版本。它引人瞩目,已经有一些供应器provider可以工作,但是从某种程度上来说还不完整,更多的是一种实验性的工具(不安全)。我认为,顾忌到许可证问题,人们会小心翼翼的为 dtrace4linux 贡献代码:由于当年 Sun 开源DTrace 使用的是 CDDL 协议,而 dtrace4linux 也不大可能最终进入 Linux kernel。Paul 的方法很可能会使其成为一个 add-on。我很乐意看到 Linux 平台上的 DTrace 和这个项目的完成,我认为当我加入 Netflix 后将会花些时间来协助完成这个项目。然而,我还是要继续使用内置的跟踪器,如 ftrace 和 perf_events。

8. OL DTrace

Oracle Linux DTrace 为了将 DTrace 引入 Linux,特别是为 Oracle Linux,做出了很大的努力。这些年来发布的多个版本表明了它的稳定进展。开发者们以一种对这个项目的前景看好的态度谈论着改进 DTrace 测试套件。很多有用的 供应器provider 已经完成了,如:syscall, profile, sdt, proc, sched 以及 USDT。我很期待 fbt(function boundary tracing,用于内核动态跟踪)的完成,它是 Linux 内核上非常棒的 供应器provider。OL DTrace 最终的成功将取决于人们对运行 Oracle Linux(为技术支持付费)有多大兴趣,另一方面取决于它是否完全开源:它的内核元件是开源的,而我没有看到它的用户级别代码。

9. sysdig

sysdig 是一个使用类 tcpdump 语法在系统事件上操作的新跟踪器,它使用 lua 进行后期处理。它很优秀,它见证了系统跟踪领域的变革。它的局限性在于它只在当前进行系统调用,将所有事件转储为用户级别用于后期处理。你可以使用系统调用做很多事情,然而我还是很希望它能支持跟踪点、kprobe 和 uprobe。我还期待它能支持 eBPF 做内核摘要。目前,sysdig 开发者正在增加容器支持。留意这些内容。