perf [1]
perf 是基于内核子系统的Linux的性能计数器,也被称为 perf_events,它提供了为所有事件进行性能分析的框架,perf 由两部分组成:
- 内核系统调用,用于提供对这些性能数据的访问
- 用户空间工具,用于提供收集,显示分析这些性能数据的用户空间程序
由于 perf 是内核的一部分,但要想使用 perf 还需要安装另外一部分,通常情况下安装的版本是Linux内核版本,如操作系统内核版本为 5.10 那么安装 linux-tool 后则为 5.10
|
|
各系统下的包名与安装
- Ubuntu/Debian:
linux-perf | linux-tools
;apt-get install linux-perf
- CentOS/Fedora:
perf
;yum install -y perf
list - 列出可用事件描述符
使用 perf 子命令 list
可以列出所有的 perf 可测量事件
|
|
list 子命令后还可以加过滤器以查看对应类型的事件,示例:
|
|
top - 查看系统实时信息
perf 的 top子命令可以查看CPU的实时信息
|
|
上面的信息的展示类似于 top
命令,从左右到信息为:
- 第一列:与CPU使用率百分比占用的相关函数
- 第二列:那个库或者进程使用的这个函数
- 第三列:[k] 表示内核空间, [.] 表示用户空间
- 第四列:符号或函数的名称
默认情况下 perf top
监控的是所有CPU,也可以使用子选项,例如下表(一些常用的命令参数)
Option | describe |
---|---|
-a | 监控所有CPU包含空闲值 |
-c | 收集 |
-C | 收集指定CPU的样本,后接CPU核心编号 |
-d | 后接数字,将延迟几秒刷新 |
-e | 指定特殊的事件,事件通过 perf list 查看 |
-F | 控制采样的频率 |
-p | 指定PID的进程的事件信息 |
-g | 启用 显示调用图记录 |
-i | 不继承模式,子任务将不继承计数器 |
-t | 指定线程ID的事件信息 |
-u | 指定user的事件信息 |
更多选项可以使用 perf top -h
stat - CPU相关统计
使用 perf 子命令 stat
可以对指定命令的CPU性能统计
|
|
查看指定命令的CPU计数器统计信息
|
|
示例
|
|
查看指定PID的CPU计数器统计信息
统计命令将会直到 ctrl - c 结束
|
|
示例:例如统计一个进程的CPU使用情况
|
|
只统计缓存信息
|
|
- LLC last-level cache 是指内存分层结构中主内存之前的最后一级
- LLC-loads:命中的指标
- LLC-load-misses:未命中指标,显示这个周期内尚未处理的比率
- LLC-stores
- LLC-prefetches:事件发生在的 L2 硬件预取中
示例:
|
|
record - 将CPU事件记录到文件
导出事件记录到文件
perf的子命令 record
是可以将事件记录到 perf.data,例如要CPU周期事件,可以使用record子命令并通过 tag -e
来指定事件名称
|
|
通过查看文件的记录
结果将保存到 perf.data 文件中,如果需要查看 perf.data 需要使用子命令 report
查看,report 子命令默认查找当前目录下的 perf.data 文件,如果需要指定特定目录的需要使用tag -i
|
|
修改样本文件输出的结果格式
report 子命令也可以改变要显示的结果样式,例如想输出为标准输出,可以使用 --stdio
|
|
如果想显示事件的编号以及对特定列排序可以使用下面域名
|
|
script - trace做了什么
perf 子命令 script 可以trace perf.data 中所有的事件;例如上面的 perf.data 最终两个事件展开为
perf script 子命令也是作为一个后期处理数据的一个命令
|
|
输出显示文件的头信息,例如跟踪何时开始、持续了多长时间、CPU信息以及获取数据的命令。 事件列表在头信息之后。
显示trace的头信息
使用tag --header
可以显示文件的头信息,例如跟何时开始trace、持续的事件、CPU信息以及获取数据的命令。 事件列表在头信息之后。事件头信息是由 # ========
包含著的信息
|
|
导出16进制的原生数据
导出原生数据是ASIIC格式事件信息
|
|
trace - 更高性能的strace的替代品
trace是linux 3.7 增加的功能,可以用作strace命令的替代品,因为不需要用户-内核空间切换,所以性能将更快
|
|
也可以使用tag -e
来指定仅对指定事件trace
|
|
可以看到对应事件将只有 read 与 write
|
|
probe - 动态追踪
perf probe子命令是可以动态的在linux内核中自定义追踪事件(追踪点),追踪点的运行时可以在被放置任何任何地方,并且每次通过该追踪点时,都可以记录其值。
如何使用 perf probe?
查看可探测的函数
perf probe -F
可以找到可用的追踪点,如果模糊查找可以使用filter
|
|
probe参数
Option | describe |
---|---|
-L | 显示源代码 |
-x | 可执行文件的名称或路径 |
-l | 列出所有probe探测事件 |
-k | 指定vmlinux文件 |
-a | **`<[EVENT=]FUNC[@SRC][+OFF |
EVENT 事件名称 | |
FUNC 函数名 | |
+OFF 函数入口的偏移量 | |
%return 探针位置为函数返回处 | |
SRC 源代码路径 | |
RL 相对函数入口处的行号 | |
AL 在文件内的绝对行号 | |
ARG: 探测参数(局部变量名 或 kprobe-tracer 参数格式。 |
|
|
一些使用示例
|
|
通过probe检测内核函数
probe使用示例说明
- 内核函数:tcp_sendmsg()
在内核函数上 tcp_sendmsg 添加一个事件
|
|
此时会存在一个追踪点,通过 perf probe -l
可以查看
trace此追踪点5s,记录堆栈信息
|
|
通过 report 子命令可以查看对应信息
|
|
删除对应跟踪点
|
|
也可以通过内核函数的变量进行检查
查看内核函数参数,可以看到存在三个参数 size
int类型, msg
结构体指针,sk
结构体指针
|
|
使用 size
变量作为 tcp_sendmsg
探测点的探测器
|
|
通过probe检测用户空间程序 [2]
准备一段代码,即每次循环,打印该值并打印该值+5
|
|
这里使用环境为 debian11,内核 5.10,需要注意的是,在新内核中版本中传参的命令与老内核有少许差别
运行编译后的程序可以看到结果
|
|
这里编译时使用了 -g
选项,-g
是一个编译选项,即在源代码编译的过程中起作用,让gcc把更多调试信息(也就包括符号信息)收集起来并将存放到最终的可执行文件
接下来为程序创建一个追踪事件,
|
|
此时可以执行这个程序,让probe可以追踪到数据
|
|
执行的结果保存在 perf.data
中
|
|
使用 script
子命令查看这个程序的trace记录,可以看到
|
|
可以通过上面看到,这里制作的探针在用户空间程序 tst.func 函数中,当他返回时,记录了要返回的值作为arg1,也就是每行返回的 0xf
这类16进制值,也可以看到每次命中该探针的部分
Troubleshooting
Uhhuh. NMI received for unknown reason
|
|
上述问题通常发生于虚拟化环境
Solve solution: disable c-state in bios
Failed to find the path for kernel: Invalid ELF file
|
|
这个错误通常使用 perf probe -V
时出现,这里需要内核支持 debug symbols,即使用公开发行版需要安装对应内核包
- RHEL/CentOS:安装
kernel-debuginfo-common
与kernel-debuginfo package
- Debian/Ubuntu:安装
linux-image-<kernel_version>-amd64-dbg
debian下保持需要至少5G空间 [3]
Failed to find source file path
|
|
思路:可以通过 strace
命令看看为什么报错
原因:perf probe -L
将显示对应内核探测点的源代码,此时perf会寻找构建的内核目录,而操作系统发行版供应商对于系统都是通过包管理,包括内核,并未提供这些源码,此状态为正确的,如果非要解决,可以自行编译内核。
dmesg
dmesg 是来自内核的一个环形缓冲区,而通过 dmesg 命令可以看到来自该缓冲区的消息,而该消息也被称为 ”driver message“ 或 ”display message“
示例1:对dmesg输出着色
|
|
示例2:dmesg输出消息增加时间
|
|
示例3:过滤相关级别信息
可以通过 --level
来进行过滤出不同级别的日志,可用级别有
- emerg,
- alert,
- crit,
- err,
- warn,
- notice,
- info
- debug
|
|
示例4:过滤相关事件信息
dmesg 可以通过参数指定 --facility
来指定对应事件的日志,可用的设施有:
- kern
- user
- daemon
- auth
- lpr
- news
|
|
示例5:实时打印dmesg日志
|
|
示例6:显示dmesg原生信息
|
|
示例7:dmesg信息重定向到syslog
dmesg本身只是一个用户空间命令,而 ”driver message“ 是内存中一个缓冲器,在Linux标识为 /dev/kmsg
,而这个缓冲区是存在与内存中,如果需要将其重定向到syslog,可以通过参数 -S
实现,-s
则是设置这个环形buffer的大小
示例8:过滤硬件设备相关信息
|
|
示例9:清空buffer
|
|
vmstat
vmstat 命令是Linux虚拟内存统计信息的命令,带来的是与进程有关的信息,如processes, memory, paging, block IO
没有任何参数的vmstat
|
|
vmstat输出包含的字段
- Procs – r: 等待运行的数量
- Procs – b: 忙碌进程的数量
- Memory – swpd: 已使用的虚拟内存
- Memory – free: 空闲的虚拟内存
- Memory – buff: 用作buffer的内存
- Memory – cache: 用作cache的内存
- Swap – si: 从磁盘交换至内存 (for every second)
- Swap – so: 内存交换到磁盘 (for every second)
- IO – bi (Blocks in). i.e 从设备接受到的块(for every second)
- IO – bo (Blocks out). i.e 发送到设备的块 (for every second)
- System – in (Interrupts per second) 每秒的中断
- System – cs (Context switches) 上下文切换
- CPU – us, sy, id, wa, st: CPU user time, system time, idle time, wait time
示例1:显示活动和非活动内存
|
|
示例2:显示启动系统后所有fork系统调用
显示所有 fork、vfork 和 clone 系统调用计数
|
|
示例3:动态展示
展示结果将以 x 秒刷新,直到 crtl - c 退出
|
|
也可以接俩个参数,一个是刷新时间,一个是刷新多少次,例如,2秒刷新一次,一共刷新10次,完成后退出命令
|
|
示例4:打印时间
|
|
示例5:显示slab相关信息
slab是一种内存管理机制,目的是为了更有效的分配内存对象
|
|
场景6:输出格式为表格形式
|
|
场景7:磁盘相关信息
|
|
场景8:输出格式增加宽度
|
|
场景9:输出单位格式化
|
|
mpstat
mpstat是统计CPU相关信息的命令
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install sysstat -y
- RHEL/CentOS/Fedora:
yum install -y sysstat
|
|
看懂 mpstat 输出结果
- CPU:处理器编号. all为所有CPU在一段时间内的平均统计信息.
- %usr:在用户级别(应用程序)执行时的CPU平均使用率。
- %nice:具有良好级别的用户级别(应用程序)执行时的CPU平均使用率。
- %sys:显示在内核级别执行时发生的CPU使用率。 这里不包括耗时的硬/软中断服务
- %iowait:CPU 或 CPU 处于空闲状态期间系统有未完成的磁盘 I/O 请求。
- %irq:一个或多个 CPU 在中断时,硬中断所花费的时间的百分比。
- %soft: 一个或多个CPU用于中断时,软中断所花费的时间百分比。
- %steal: 一个或多个虚拟CPU当在虚拟机管理器服务与另一个虚拟处理器时非自愿等待时间所花费的百分比
- %guest:一个或多个CPU在运行一个虚拟处理器使用时间的百分比
- %idle : 一个或多个CPU处于idle状态,并且系统没有尚未完成的磁盘 I/O 请求
|
|
pidstat
pidstat 是 sysstat 包的一部分,可以统计单个进程并生成报告。用以通过 PID 来评估资源的使用率
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install sysstat -y
- RHEL/CentOS/Fedora:
yum install -y sysstat
|
|
iostat
iostat 是 sysstat 包的一部分,可以通过命令来统计CPU使用率, I/O, (设备,分区), 网络文件系统等
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install sysstat -y
- RHEL/CentOS/Fedora:
yum install -y sysstat
iostat命令参数
- -c: 显示CPU使用率
- -d: 显示设备使用率
- -k: 以kb为单位统计(每秒)
- -m: 以mb为单位统计(每秒)
- -x: 展示一些扩展的统计文件
iostat结果为两部分,avg-cpu 与 Device,均是指自开机以来的统计
avg-cpu部分:
- %user:在用户级别(应用程序)执行时的CPU平均使用率。
- %nice:具有良好级别的用户级别(应用程序)执行时的CPU平均使用率。
- %system:显示在内核级别执行时发生的CPU使用率。 这里不包括耗时的硬/软中断服务
- %iowait:CPU 或 CPU 处于空闲状态期间系统有未完成的磁盘 I/O 请求。
- %steal: 一个或多个虚拟CPU当在虚拟机管理器服务与另一个虚拟处理器时非自愿等待时间所花费的百分比
- %idle : 一个或多个CPU处于idle状态,并且系统没有尚未完成的磁盘 I/O 请求
Device部分:
- tps - 表示每秒发送给设备的传输次数。
- Blk_read/s (kB_read/s, MB_read/s) - 表示每秒从设备读取的数据量,以块(KB、MB)表示。
- Blk_wrtn/s (kB_read/s, MB_read/s) - 表示每秒写入设备的数据量,以块(KB、MB)表示。
- Blk_read (kB_read, MB_read) - 读取块总数(KB、MB)
- Blk_wrtn (kB_read, MB_read)- 写入块总数(KB、MB)
|
|
使用示例
|
|
htop
htop可以理解为linux中的与windows任务管理器相同的产品,与top不同的是,htop是一个支持交互式的top命令
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install htop -y
- RHEL/CentOS/Fedora:
yum install -y htop
CPU和内存使用状态
htop上部屏幕,为CPU和存储使用详情
显示的颜色
默认模式
- 蓝色:低优先级进程(nice> 0)
- 绿色:正常(用户)流程
- 红色:内核时间(内核,iowait,irqs …)
- 橙色:有效时间(窃取时间+访客时间)
详细模式
- 蓝色:低优先级线程(nice> 0)
- 绿色:正常(用户)流程
- 红色:系统进程
- 橙色:IRQ时间
- 洋红色:IRQ时间较慢
- 灰色:IO等待时间
- 青色:偷时间
- 青色:访客时间
内存计量器更简单:
- 绿色:已用内存页
- 蓝色:缓冲页
- 橙色:缓存页面
可以通过f1查看帮助对于颜色的说明
ldd
sar
sar System Activity Report的简写,可以用于收集、报告或保存系统活动的统计信息,如 Linux 系统中的 CPU 利用率、内存使用情况、I/O 设备使用情况。 sar 命令显示自系统启动以来的平均统计信息。它在输出中生成报告,也可以保存在文件中。
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install sysstat -y
- RHEL/CentOS/Fedora:
yum install -y sysstat
Notes:sar是服务,需要开启收集才可以查询到,配置
/etc/default/sysstat
修改为ENABLED="false"
然后重启服务systemctl restart sysstat.service
sar语法
|
|
更多可以参考 [5]
ioping
ioping是一款磁盘延迟监控工具
- Ubuntu/Debian/Mint:
apt install -y ioping
- RHEL/CentOS/Fedora:
yum install -y ioping
Option | describe |
---|---|
-c count | ping的次数 |
-i interval | 每次请求的间隔 |
-t time | 最大有效的请求事件,太慢的请求将被忽略 |
-s size | 请求大小 |
-S wsize | |
-o offset | 在 file/device 开始的偏移量 |
-w deadline | 在多少时间后停止 |
-p period | 打印每秒请求的原生统计数据 |
-A | 使用异步IO (syscalls io_submit(2), io_submit(2), |
-B | 批量模式,以安静的原始数据方式统计最终的数据 |
-C | 使用 cached I/O 在posix_fadvise(2)读取之前 和写入 fdatasync(2)之后,来抑制缓存失效。 |
-D | 使用direct I/O (O_DIRECT in open(2)). |
-L | 使用序列操作而不是随机操作,这相当于设置了默认大小,例如 -s 256k 与这个是相同的 |
-R | 磁盘查找速度测试,这个选项将以人类可读模式输出每个请求 设置默认间隔为0, -i=0 停止测量将在3秒后停止 -w=3 设置工作集大小为64m -S=64m |
-W | 写而不是读。目录目标安全。写入 I/O 为不支持或在某种级别缓存非缓存读取从而提供更可靠的结果。对于file/device来说是危险的:这将会粉碎数据。 |
-Y | 使用同步IO (O_SYNC in open(2)). |
-y | 使用数据同步IO (O_DSYNC in open(2)). |
-k | 重用临时工作目录文件 “ioping.tmp” (仅对于目标目录生效) |
-q | Suppress periodical human-readable output. |
使用示例
RAW STATISTICS
|
|
上面输出的结果意思为:
- 统计请求的计数
- 运行时间 usec 微秒
- 每秒请求 (iops)
- 传输速率 (bytes/sec)
- 最小请求时间 (usec)
- 平均请求时间 (usec)
- 最大请求时间 (usec)
- 请求时间偏差 (usec)
- 总请求 (包含很慢和很快的)
- 总共运行时间 (usec)
|
|
vnstat
vnstat是 Linux 中用于监控网络参数的命令,通常查看带宽消耗或一些流入或流出的流量,与网络接口上的流量。
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install -y vnstat
- RHEL/CentOS/Fedora:epel
yum install -y vnstat
vnstat是一个守护进程,如果需要记录需要启动这个服务才可以,而不是一个单独的命令
|
|
ifstat
ifstat是Linux下网络接口统计的命令
- Ubuntu/Debian/Mint:
apt install -y ifstat
- RHEL/CentOS/Fedora:
yum install -y ifstat
|
|
iptraf
iptraf是Linux 中交互式的网络监控命令,通过交互式实现展示
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install -y iptraf-ng
- RHEL/CentOS/Fedora:
yum install -y iptraf-ng
iftop
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install -y iftop
- RHEL/CentOS/Fedora:epel
yum install -y iftop
|
|
arpwatch
arpwatch是Linux上用于监视ARP记录的
各系统下的包名与安装
- Ubuntu/Debian/Mint:
apt install -y arpwatch
- RHEL/CentOS/Fedora:epel
yum install -y arpwatch
Option | describe |
---|---|
-d | debug模式 |
-f | 设置用于存储 ethernet/ip address 的文件,默认在 /var/arpwatch/arp.dat |
-i | 指定默认接口 |
-n | 指定本地网络 |
-u | 指定用户或用户组 |
-Q | The flags prevents arpwatch from sending reports by mail |
-z | 设置忽略的 IP范围,IP和掩码用 “/” 化为,如 -z 192.168.10.0/255.255.255.0 |
|
|
Reference
[1] perf Examples
[2] User-space introspection with Linux perf