工具卡
每张卡说一件事:这个工具能回答什么问题、看哪几列、什么样的数算不正常、装哪个包、要不要 root、嵌入式板子上用什么代替,以及书里在哪一节讲它。包名按 Debian/Ubuntu;BCC 工具在 Debian 上名字带 -bpfcc 后缀(runqlat-bpfcc)。卡片是本站写的,命令的完整选项看各自的 man 页。
全局统计
uptimeprocps
回答负载在涨还是在落。
看1、5、15 分钟三个负载平均的走向。Linux 上含等磁盘的任务,不能单独当 CPU 指标。直接读 /proc/loadavg 是同一组数。
ARM 板busybox 一般带 uptime;/proc/loadavg 总在。
§6.6.1
vmstatprocps
回答全系统 CPU 忙不忙、有没有在排队、有没有在换页。
看r(在跑加排队,长期大于核数是饱和)、b(不可中断睡眠)、si/so(换入换出,持续不为零就是在换页)、us/sy/id/wa/st。第一行是开机以来的平均,从第二行看。
ARM 板busybox 可能带 vmstat;没有就读 /proc/stat 和 /proc/vmstat。
§6.6.2 §7.5.1
mpstatsysstat
回答每个 CPU 各忙在哪:用户态、内核态、中断、等 IO、被偷走。
看mpstat -P ALL 1:单个核 %usr+%sys 接近 100% 而别的闲着,是单线程或中断集中;%soft、%irq 集中在某个核说明中断没摊开;%steal 是虚拟机被宿主拿走的时间。
ARM 板读 /proc/stat 每个 cpuN 行,隔一秒相减。
§6.6.3
sarsysstat
回答和 mpstat、iostat、网络统计一样的数,但能看历史(开了 sysstat 的定时采集之后)。
看sar -u、-q(运行队列和负载)、-r(内存)、-d(磁盘)、-n DEV/EDEV/TCP/ETCP(网络);sar -f 文件 回看某一天。
ARM 板sysstat 可以交叉编译;历史数据要定时任务和存储空间。
§4.4 §6.6.4 §10.6.6
dmesgutil-linux
回答内核刚才报了什么:OOM、硬件错误、降频、丢包、文件系统错误。
看dmesg -T | tail;搜 Out of memory、Killed process、I/O error。
ARM 板busybox 带 dmesg(没有 -T 时间换算)。
§1.10.1
/proc/pressure内核接口
回答任务因为等 CPU、内存、IO 而停顿了多少时间。
看cat /proc/pressure/cpu(还有 memory、io):some avg10 是最近 10 秒里至少一个任务在等的时间比例;full 是所有非空闲任务都在等的比例。
ARM 板内核要开 CONFIG_PSI(4.20 起)。
§6.6.1 §7.5.2 §9.6.3
sadfsysstat
回答把 sar 存下的历史数据导出成 CSV、JSON、SVG 图,方便画图或交给别的工具。
看sadf -d 文件 -- -u 导出 CPU 数据;-g 出 SVG。数据要先由 sysstat 的定时采集(或 sadc)写下来。
权限读数据文件不要 root。
ARM 板sysstat 交叉编译后可用。
§4.4
systemd-analyzesystemd
回答开机慢在哪个服务。
看systemd-analyze blame 按耗时排序;critical-chain 给出决定总时长的那条依赖链,先优化链上的。
权限看启动时间不用 root。
ARM 板不用 systemd 的 BSP 没有它;可以用内核的 initcall_debug 加 dmesg 时间戳看内核阶段。
§3.4.2
进程和线程
topprocps
回答现在谁最占 CPU、内存。
看按 1 看每个核,按 H 看线程。%CPU 在 Linux 上不除以核数,两个线程跑满是 200%。top 会漏掉短命的进程,自己的开销也不小。
ARM 板busybox top 字段较少。
§6.6.6
psprocps
回答进程和线程的状态、累计 CPU、内存。
看Linux 上 %CPU 是进程从启动到现在的平均,不是当前值;状态列 D 是不可中断睡眠。ps -eLo pid,tid,stat,comm 看线程。
ARM 板busybox ps 字段少,读 /proc/PID/status、/proc/PID/task/*/stat。
§6.6.5 §7.5.7
pidstatsysstat
回答每个进程、线程的 CPU、内存、IO、上下文切换,按秒滚动。
看pidstat 1:%usr/%system/%wait(等 CPU);-t 线程;-r 缺页和 RSS;-d 读写字节;-w 自愿和非自愿上下文切换。
ARM 板读 /proc/PID/stat、/proc/PID/io、/proc/PID/status 自己差分。
§6.6.7 §9.6.4
stracestrace
回答进程在做哪些系统调用、每个花了多久。
看strace -c -f -p PID 汇总;-T 显示每次调用的耗时。开销很大,会让被跟踪的程序明显变慢,生产上只短时间用;只用 -e 选几种调用也一样慢,因为每个系统调用都要停一次。strace 5.3 起有 --seccomp-bpf(要配 -f):只在选中的调用上停,选中的调用少时开销小得多,但只对 strace 自己启动的进程有效,-p 挂上去的用不上。本站在 WSL2 上实测:dd 小块拷贝只跟踪 openat,普通 strace 慢了三百多倍,加 --seccomp-bpf 后几乎不慢。
权限跟踪自己启动的程序不要 root。kernel.yama.ptrace_scope 为 1 时(本站 WSL2 就是 1),-p 挂已经在跑、又不是自己子进程的进程,哪怕是自己的进程,也要 root 或 CAP_SYS_PTRACE。
ARM 板strace 容易交叉编译,Buildroot、Yocto 里都有。
§5.5.4 §8.6.7
execsnoopbpfcc-tools
回答有哪些短命的进程在不停地被启动(top 看不到它们)。
看每一行一次 exec,带参数。频繁调用 shell 脚本、外部命令的服务常因此费 CPU。要 root。
ARM 板没有 BPF 时,可以用 ftrace 的 sched_process_exec 跟踪点。
§5.5.5
syscountbpfcc-tools
回答全系统或某个进程,哪些系统调用最多、各花了多少时间。开销比 strace 小得多。
看syscount-bpfcc;-P 按进程,-L 带上耗时。某个调用每秒几十万次(比如很小的 read、write),就是可以合并的信号。
权限要 root。
ARM 板没有现成替代;/proc/PID/io 的 syscr、syscw 能数读写类调用;能交叉编译 strace 时用 strace -c -p PID 挂几秒。
§5.5.6 §15.1.3
lsnsutil-linux
回答机器上有哪些命名空间、各有多少进程。
看看 TYPE、NPROCS;同一类型出现好几个 ID,说明有容器或被隔离的进程。
权限不用 root 只列自己的进程,看全部要 root。
ARM 板手工比对 ls -l /proc/*/ns/。
§11.3.1
nsenterutil-linux
回答在宿主上进入某个进程的命名空间,用宿主上的工具查容器。
看nsenter -t PID -n 进容器的网络栈跑 ss、tcpdump;-m -p 只看到容器的进程,但 top 头部的汇总仍是宿主的。
权限要 root。
ARM 板busybox 可能编进了 nsenter(看裁剪配置)。
§11.3.4
systemd-cgtopsystemd
回答按 cgroup(容器、服务)看谁在用 CPU、内存、IO。
看按 %CPU、Memory 排;某个容器的 %CPU 贴着它的限额(限 2 颗就是 200%)就是到顶了。
权限读自己能读的 cgroup 不用 root,看全部要 root。
ARM 板没有 systemd 时直接读 /sys/fs/cgroup 下各目录的 cpu.stat、memory.current。
§11.3.4
xentopXen 工具(包名随版本)
回答Xen 宿主上每个客户机的 CPU、内存、网络、块设备。
看CPU(%) 是几个 vCPU 加起来的;VBD_OO 不为零说明块设备请求在排队。
权限在 dom0 用 root 跑。
ARM 板无。
§11.2.4
CPU 剖析和调度
perflinux-perf(Ubuntu 上是 linux-tools-$(uname -r))
回答CPU 时间花在哪些函数上(采样剖析);周期、指令、缓存未命中有多少(计数);跟踪点和动态探针。
看perf record -F 99 -g -p PID -- sleep 30 再 perf report;perf stat 看 IPC。看到十六进制地址是缺符号,栈只有一两层是缺帧指针。
权限非 root 时受 kernel.perf_event_paranoid 限制,默认值因发行版和内核而异,有的发行版内核默认不许非特权用户用 perf。为 2 时只能剖析自己这个用户的进程(自己启动的,或者用 -p 挂上去的),基本只看用户态(本站 WSL2 实测)。
ARM 板从内核源码 tools/perf 交叉编译,或在 Buildroot、Yocto 里选上。
§6.6.13 §13.1
profilebpfcc-tools
回答和 perf record 一样的 CPU 剖析,但栈在内核里汇总,开销更低。
看profile-bpfcc -F 49 30;-f 输出折叠格式,能直接画火焰图。要 root。
§6.6.14 §5.5.2
runqlatbpfcc-tools
回答线程每次在运行队列里等了多久(调度延迟的分布)。
看runqlat-bpfcc 10 1 的直方图:毫秒级的桶里有数,多半是 CPU 不够或被限流。跟踪每次调度,繁忙的机器上开销可观。要 root。
§6.6.16
runqlenbpfcc-tools
回答运行队列有多长(采样)。比 runqlat 便宜。
看runqlen-bpfcc 10 1:长度为 0 的比例越高越好;-C 按 CPU 分开。要 root。
§6.6.17
softirqs / hardirqsbpfcc-tools
回答软中断、硬中断各花了多少 CPU 时间(剖析器常看不到这部分)。
看softirqs-bpfcc 10 1、hardirqs-bpfcc 10 1。要 root。不用 BPF 时,/proc/softirqs、/proc/interrupts 给出次数,mpstat 的 %soft、%irq 给出占比。
§6.6.18 §6.6.19
offcputimebpfcc-tools
回答线程不在 CPU 上的时候在等什么、等了多久(锁、IO、睡眠),带调用栈。
看offcputime-bpfcc -p PID 10;可以画成 off-CPU 火焰图。要 root,开销比 CPU 剖析大。
§5.5.3 §5.4.2
cpudistbpfcc-tools
回答线程每次上 CPU 连续跑了多久(分布)。
看cpudist-bpfcc -p PID 10 1:大量落在几微秒,说明线程刚上 CPU 就被换走(常是 CPU 饱和、非自愿切换);-O 看离开 CPU 的时间。
权限要 root。
ARM 板粗看可以读 /proc/PID/status 里两种上下文切换的次数。
§6.6.15
内存
freeprocps
回答还有多少内存可用,文件缓存占了多少。
看free -m 的 available(还能给新程序用的估计值),不是 free;buff/cache 大通常是好事。
ARM 板busybox free 可能没有 available 列,读 /proc/meminfo 的 MemAvailable。
§8.6.2
pmapprocps
回答一个进程的内存都映射了什么:堆、栈、共享库、映射的文件,各占多少。
看pmap -x PID 的 RSS 列,按大小排;匿名内存(堆)在涨还是文件映射在涨。/proc/PID/smaps_rollup 是汇总。
§7.5.9
slabtopprocps
回答内核对象缓存(slab)占了多少内存,哪一类最大。
看按大小排的缓存名;dentry、inode 很大常因为文件很多。要能读 /proc/slabinfo(通常要 root)。
§7.5.5 §8.6.6
memleakbpfcc-tools
回答一段时间里分配了却没释放的内存,以及分配它的调用路径。
看memleak-bpfcc -p PID;它分不清泄漏和正常增长,要看代码判断。开销不小。要 root。
§7.4.6
numastatnumactl
回答多插槽机器上,内存分配有多少落在本地节点。
看numa_miss、numa_foreign 相对 numa_hit 偏高,说明远程访问多;只有一个节点就不用看。
权限不要 root。
ARM 板ARM 板多为单节点;读 /sys/devices/system/node/node*/numastat。
§7.5.6
drsnoopbpfcc-tools
回答直接回收发生在哪个进程、每次卡了多久。
看LAT(ms) 和出现的频率;频繁出现几毫秒的,就是内存紧张在拖慢应用。
权限要 root。
ARM 板没有替代;退而看 /proc/vmstat 的 allocstall_*、pgscan_direct 在不在涨。
§7.5.11
文件和磁盘
iostatsysstat
回答每块盘的 IOPS、吞吐、平均延迟、队列长度、利用率。
看iostat -xz 1:r/s、w/s、rkB/s、wkB/s、r_await、w_await、aqu-sz、%util。%util 在 SSD 和阵列上会误导(它们能并行),以延迟和队列为准。
ARM 板读 /proc/diskstats 自己差分;busybox 可能带 iostat。
§9.6.1
cachestatbpfcc-tools
回答页缓存(文件缓存)的命中率。
看cachestat-bpfcc 1 的命中、未命中和命中率。命中率低说明读在打到盘上。要 root。
§8.6.12
ext4slower / ext4distbpfcc-tools
回答文件系统这一层的操作有多慢:哪些读、写、打开、同步慢于某个阈值,延迟分布如何。从应用感到的延迟量起。
看ext4slower-bpfcc 10 列出慢于 10 毫秒的操作;ext4dist-bpfcc 给直方图。xfs、btrfs 等有对应版本。要 root。
§8.6.13 §8.6.14
biolatencybpfcc-tools
回答块设备 IO 的延迟分布。
看biolatency-bpfcc 10 1 的直方图:双峰(缓存命中和未命中、读和写)、长尾。-D 按盘分开。要 root。
§9.6.6
biosnoopbpfcc-tools
回答每一次块 IO:哪个进程、哪块盘、读还是写、多大、多久。
看按延迟找出最慢的那几次,再看它们的共同点。输出量大,短时间用。要 root。
§9.6.7
opensnoopbpfcc-tools
回答谁在打开哪些文件、哪些打开失败了。
看同一个文件反复出现,说明在重复打开;-x 只列失败的,找缺失的配置和库;-n 按进程名过滤。
权限要 root。
ARM 板对单个进程用 strace -e trace=openat -p PID;内核开了 ftrace 时可以挂 openat 的跟踪点。
§8.6.10 §15.1.3
filetopbpfcc-tools
回答哪个文件读写最多。
看按读写字节排序的 READS、R_Kb 等列,找出意外忙碌的文件;-C 不清屏。
权限要 root。
ARM 板看 /proc/PID/io 的 rchar、wchar,粗看进程级。
§8.6.11
fatracefatrace
回答全系统的文件访问事件(基于 fanotify)。
看O 打开、R 读、W 写、C 关闭;忙的系统上输出极多、开销不小。
权限要 root。
ARM 板内核开了 fanotify 时可以交叉编译。
§8.6.8
biotopbpfcc-tools
回答哪个进程在发磁盘 IO、发了多少、平均多慢。
看I/O、Kbytes、AVGms 三列;PID 是尽力而为的,IO 由内核线程下发时可能对不上。
权限要 root。
ARM 板读 /proc/PID/io。
§9.6.8
iotopiotop(或 iotop-c)
回答按线程排序的磁盘读写速率和等 IO 的时间比例。
看DISK READ、DISK WRITE、IO%;Linux 5.14 起 delay accounting 默认关闭,要用启动参数 delayacct 或 sysctl kernel.task_delayacct=1 打开,IO% 才有数(用 sysctl 打开时,之前已经在跑的进程不计)。书里提醒它的计数要用已知负载验证。
权限要 root。
ARM 板无。
§9.6.8
biostacksbpftrace(biostacks.bt)
回答磁盘 IO 是哪条内核调用路径发出来的,各条路径的延迟分布。
看看栈里是哪种文件系统操作(路径查找、日志、后台回写),哪条栈的延迟偏高。
权限要 root。
ARM 板内核开了 ftrace 时,用 tracefs 的 block 跟踪点加栈。
§9.6.9
blktrace / bttblktrace
回答每个 IO 在块层各阶段(排队、合并、下发、完成)的时间。
看btt 的 D2C(在盘上的时间)、Q2C(块层全程);最大值大说明有离群值。
权限要 root。
ARM 板内核开了 CONFIG_BLK_DEV_IO_TRACE 时可以交叉编译。
§9.6.10
smartctlsmartmontools
回答盘的健康:纠正过的错误、重映射扇区、温度、自检结果。
看纠错次数、重映射扇区数在涨,说明盘快坏了;单个慢 IO 它回答不了。
权限要 root。
ARM 板eMMC 可以看 mmc-utils 读出的寿命字段(看你的 BSP)。
§9.6.13
iopingioping
回答单次 IO 有多慢,施加的负载很轻。
看每次请求的 time,最后的 min/avg/max/mdev;生产机上也能跑。
权限读普通文件不要 root。
ARM 板可以交叉编译。
§9.8.5
fiofio
回答文件系统或磁盘在给定 IO 大小、随机比例、并发下的 IOPS、吞吐和延迟分布。
看IOPS、带宽、延迟百分位(clat percentiles);不加 --direct=1 测到的是页缓存。测的时候开着 iostat 对照。
权限测普通文件不要 root,测裸设备要。
ARM 板可以编进 Buildroot、Yocto;没有时用 dd 加 oflag=direct 粗测。
§9.8.6 §12.2.1
网络
ssiproute2
回答套接字的状态和每个 TCP 连接的内部指标。
看ss -tin:rtt、cwnd、retrans、发送和接收队列;ss -lnt:监听套接字的 Recv-Q(当前排队的连接)和 Send-Q(队列上限)。
ARM 板busybox 有 netstat,没有 ss 时读 /proc/net/tcp。
§10.6.1
nstatiproute2
回答内核网络计数器的增量:重传、丢包、监听队列溢出。
看nstat -z:不带 -a 时显示上次运行以来的增量(第一次跑是开机以来的累计),-a 总是给累计值,-z 连为零的也列出。关心 TcpRetransSegs、TcpExtListenOverflows、TcpExtListenDrops、TcpExtTCPTimeouts。
ARM 板数据来自 /proc/net/snmp 和 /proc/net/netstat,可以直接读。
§10.6.4
ipiproute2
回答网卡的状态和收发统计、错误、丢包。
看ip -s link 的 errors、dropped、overrun。
§10.6.2
ethtoolethtool
回答网卡协商的速率和双工、驱动层的统计、队列和卸载设置。
看ethtool 网卡名 的 Speed、Duplex;ethtool -S 网卡名 驱动计数器(名字因驱动而异)。
§10.6.8
tcpdumptcpdump
回答线上到底收发了哪些包,握手、重传、窗口长什么样。
看tcpdump -i 网卡名 -w 文件 port 端口 抓下来再用 Wireshark 看。包多时开销大,用过滤器、写文件。要 root。
§10.6.13
tcpretransbpfcc-tools
回答每一次 TCP 重传:哪个连接、什么状态。
看重传集中在哪些对端地址。只在重传时触发,开销低。要 root。
§10.6.11
netstatnet-tools
回答各种网络计数和套接字列表(老工具)。
看netstat -s 看 listen queue overflowed、segments retransmitted;-i 看各网卡的 RX-DRP、RX-OVR。都是累计值,隔几秒看增量。书里提到内核网络开发者认为 net-tools 已经过时(§10.6 开头),iproute2 的 ss、ip、nstat 对新内核特性支持得最好。
权限不要 root。
ARM 板busybox 可能编进了 netstat(字段少);没有就读 /proc/net/snmp、/proc/net/netstat。
§10.6.5
tcplifebpfcc-tools
回答每条 TCP 连接活了多久、收发多少、属于哪个进程。
看MS 列是寿命,TX_KB、RX_KB 是收发量;短命连接太多,说明没做连接复用。开销小,可以常开。
权限要 root。
ARM 板要内核支持 BPF,板子上通常没有。
§10.6.9
tcpsynblbpfcc-tools;bpftrace(tcpsynbl.bt)
回答监听队列离满还有多远。
看每个 backlog 上限一张队列长度的直方图,贴近上限说明快要丢 SYN 了;bpftrace 的 tcpsynbl.bt 在队列超过上限时还会打印 dropping a SYN(BCC 版不打印)。
权限要 root。
ARM 板用 ss -lnt 的 Recv-Q、Send-Q,或读 /proc/net/netstat 的 ListenOverflows。
§10.6.12
iperf3iperf3
回答两台机器之间 TCP、UDP 的最大吞吐。
看单向吞吐和重传数(Retr);同时在接收端开 mpstat -P ALL 1,看是不是某个核的 %soft 先满。
权限不要 root。
ARM 板可以交叉编译,体积小。
§10.7.4 §12.2.1
wrkwrk
回答HTTP 服务的吞吐和延迟分布。
看加 --latency 看延迟分布;有错误响应先查错误再看吞吐;压测端单个线程 100% 时,测到的是 wrk 自己。
权限不要 root。
ARM 板一般在另一台机器上跑,不在板子上跑。
§12.2.2
跟踪框架
bpftracebpftrace
回答任何具体问题,现场写一行:某个函数被谁调用、耗时分布、按进程计数。
看单行命令输出的计数和直方图。要 root,内核要支持 BPF(有 BTF 更省事)。
§15.2 §6.6.20
Ftrace(tracefs)内核接口
回答内核函数和跟踪点的事件、调用图、计数,不需要装任何东西。
看/sys/kernel/tracing 下的 current_tracer、set_ftrace_filter、trace_pipe。要 root,内核要开 ftrace。板子上没有 BPF 时最后的依靠。
§14.2
trace-cmdtrace-cmd
回答和直接操作 tracefs 一样,但用命令行包装好了:记录、报告、function_graph。
看trace-cmd record -p function_graph -g 函数名,再 trace-cmd report。要 root。
§14.11
funccountbpfcc-tools(funccount-bpfcc);perf-tools-unstable(funccount-perf)
回答内核函数、用户函数或跟踪点每秒被调用多少次。
看BCC 版 -i 1 每秒一行,和请求速率比,看本该只调一次的函数是不是每个请求都在调。perf-tools 版基于 Ftrace 的函数剖析器,内核要开 CONFIG_FUNCTION_PROFILER。
权限都要 root。
ARM 板在跟踪点上挂 hist:keys=… 数次数。
§14.13.5 §15.1.4
funclatencybpfcc-tools
回答一个函数的耗时分布(直方图)。
看有两个峰说明有快慢两条路径;-u 用微秒;函数很快时探针自己的开销会把数字拉高,用户函数的 uprobe 尤其明显。
权限要 root。
ARM 板无。
§15.1.4
argdistbpfcc-tools
回答函数参数或返回值的分布。
看-H 出直方图、-C 计数;比如 write 一堆几字节的小写,往往是没加缓冲。
权限要 root。
ARM 板无。
§15.1.4
stackcountbpfcc-tools
回答哪些调用栈触发了某个事件或函数。
看排在前面的栈就是调用最多的路径;-U 只看用户栈、-K 只看内核栈;栈断了先查帧指针。
权限要 root。
ARM 板无。
§15.1.4
trace(BCC)bpfcc-tools(trace-bpfcc)
回答逐次打印某个函数的调用、参数和调用栈。
看一次调用一行,格式仿 printf;事件多时会刷屏,只适合低频函数。
权限要 root。
ARM 板tracefs 的 kprobe、uprobe 事件。
§15.1.6
funcgraphperf-tools-unstable(funcgraph-perf)
回答某个内核函数里调了哪些子函数、每层花了多久。
看左边的耗时列,带 # 的超过 1 毫秒、! 的超过 100 微秒;-m 限层数,-p 限 PID。
权限要 root。
ARM 板直接写 tracefs:set_graph_function,再 echo function_graph > current_tracer。
§14.13.3 §14.8
KernelSharkkernelshark
回答trace-cmd 录下的 trace.dat 里,各 CPU、各线程是怎么交错运行的。
看上方是每个 CPU 的时间线,下方是事件表;看线程之间的等待和抢占。
权限看图不要 root,录制要 root。
ARM 板在板子上用 trace-cmd record 录,拿到桌面上看。
§14.11.5