systemtap SystemTap 是一种动态追踪和分析工具,允许用户通过编写脚本实时监控内核及用户空间程序的运行状态,常用于性能调优、故障排查和内核行为分析
核心组件
SystemTap 工具链: 包含 stap(脚本编译器)、staprun(内核模块加载器)等工具。
内核支持: 依赖 kernel-devel、kernel-debuginfo 包(提供内核符号和调试信息)。
脚本库(Tapsets): 预定义的探针和函数库,简化脚本编写(如 syscall.* 表示系统调用探针)。
工作流程
编写脚本 :用户编写 .stp
脚本,定义探针和触发动作(如记录数据、统计计数)。
编译脚本 :stap
将脚本转换为 C 代码,并编译为内核模块(.ko
文件)。
加载模块 :staprun
将模块插入内核,开始监控。
收集数据 :探针触发时执行脚本逻辑,结果输出到终端或文件。
卸载模块 :监控结束后,自动或手动移除内核模块。
安装与使用systemtap 正常情况下,SystemTap脚本只能在安装了SystemTap的系统上运行。这可能意味着在要分析的每个系统上安装完整的SystemTap编译器、内核头文件、源代码和debuginfo内核包也就是,需要一个专门的systemtap机器
1 2 3 4 5 6 7 8 9 10 11 12 13 yum -y install systemtap 会自动安装kernel-debuginfo stap-prep yum-config-manager --enable debuginfo yum clean all yum makecache yum install -y kernel-devel-$(uname -r) kernel-debuginfo-$(uname -r)
stap命令 是systemtap的前端
当脚本第一次编译时,systemtap会 在用户的家目录里面的.Systemtap目录中缓存一个已编译对象。如果检测到源脚本未被修改,则stap将在后续运行中使用缓存的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 脚本执行的五个阶段pass: 1.parse 检查语法错误 2.elaborate 函数展开 3.translate 将脚本转换成C文件 4.build 将C源文件编译成内核模块 5.run 将编译好的内核模块插入内核 stap -v /usr/share/systemtap/examples/process/syscalls_by_proc.stp Pass 1: parsed user script and 473 library scripts using 272056virt/69204res/3508shr/65836data kb, in 250usr/30sys/276real ms. Pass 2: analyzed script: 4 probes, 2 functions , 101 embeds, 5 globals using 290032virt/87984res/6496shr/81712data kb, in 14520usr/4510sys/6555real ms. Missing separate debuginfos, use: debuginfo-install kernel-3.10.0-1160.119.1.el7.x86_64 Pass 3: translated to C into "/tmp/stap98YNhM/stap_e2f1b5cd07262cd74d245a3f7b5661e9_132280_src.c" using 290032virt/88188res/6700shr/81712data kb, in 10usr/0sys/20real ms. Pass 4: compiled C into "stap_e2f1b5cd07262cd74d245a3f7b5661e9_132280.ko" in 7260usr/1380sys/8331real ms. Pass 5: starting run. Collecting data... Type Ctrl-C to exit and display results
eBPF 允许用户在不修改内核源码或加载内核模块的情况下,安全、高效地运行自定义程序 ,用于实时监控、网络处理、安全控制等场景
从用户空间 启用的,受限于它所使用的内存数量,并且对设备的访问受限
工作原理是将程序附加到各种内核点,如kprobes、跟踪点和perf事件。有许多性能分析工具利用了扩展的内核功能,不仅允许过滤数据包。这些增强允许在Linux上执行定制的分析程序,用于动态跟踪、静态跟踪和分析事件
已成为Linux内核观测和网络优化的标准方案
特性
eBPF
SystemTap
安全性
通过验证器确保安全,默认允许生产环境使用。
依赖手动审查,可能引发内核崩溃。
性能开销
极低(JIT编译 + 高效事件绑定)。
较高(依赖临时模块和脚本解释)。
内核版本要求
需要较新内核(4.x 以上)。
支持旧内核,但功能受限。
编程复杂度
需掌握C语言和BPF API,工具链完善。
脚本化开发,但调试复杂。
社区趋势
已成为Linux内核观测和网络优化的标准方案。
逐渐被eBPF替代(如RHEL 9默认支持eBPF)。
BCC工具集 编写eBPF程序需要从内核源代码编译并链接到eBPF库。这对于内核开发人员来说很好,但是对于其他人来说,比如那些在生产系统上工作的人,拥有现有的程序可能是更理想的方法。BCC包含编写程序所需的组件,还提供了示例程序和用于调试和诊断性能问题的现有工具。
BCC是一套基于 eBPF 技术的开源工具集,旨在简化 eBPF 程序的开发、调试和部署。它通过提供高层语言接口(如 Python、Lua)和预封装的内核观测工具,让开发者无需深入掌握底层内核细节即可快速实现性能分析、网络监控、安全控制等功能。
1 2 3 4 5 6 7 8 yum -y install bcc-tools 默认路径/usr/share/bcc/tools/ 也可以加到PATH中 工具文档: /usr/share/bcc/tools /usr/share/bcc/tools/doc
execsnoop 追踪execve()系统调用execsnoop追踪execve()系统调用并且展示参数和返回值的细节
1 2 3 4 5 6 7 8 9 10 11 12 13 cd /usr/share/bcc/tools/./execsnoop PCOMM PID PPID RET ARGS sshd 117876 57783 0 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cb -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2- -oGSSAPIKexAlgorithms=gss-curve25519-sha256-,gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gss-grou -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-h -oHostKeyAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v0 -oPubkeyAcceptedKeyTypes=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-ce -oCASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rs -R unix_chkpwd 117878 117876 0 /usr/sbin/unix_chkpwd root nonull unix_chkpwd 117879 117876 0 /usr/sbin/unix_chkpwd root chkexpiry sshd 117881 57783 0 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-pol PCOMM: 父进程的命令名称 PID: 进程ID PPID: 父进程ID RET: 返回值 ARGS: 带参数的文件名
opensnoop追踪open()系统调用 opensnoop工具追踪open()系统调用,列出进程的名字和路径名字细节。opensnoop是一个在应用启动期间非常有用的发现配置文件和日志文件 的工具
1 2 3 4 5 6 7 8 9 10 11 12 13 cd /usr/share/bcc/tools/./opensnoop PID COMM FD ERR PATH 772 irqbalance 6 0 /proc/interrupts 772 irqbalance 6 0 /proc/stat 772 irqbalance 6 0 /proc/irq/29/smp_affinity 772 irqbalance 6 0 /proc/irq/27/smp_affinity 772 irqbalance 6 0 /proc/interrupts 772 irqbalance 6 0 /proc/stat 772 irqbalance 6 0 /proc/irq/29/smp_affinity 772 irqbalance 6 0 /proc/irq/27/smp_affinity 敲回车,irqbalance为了监控中断状态,它会周期性地读取/proc中的文件
xfsslower追踪XFS操作 xfsslower显示xfs文件系统的读,写,打开,文件同步,默认查看慢于10ms的进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ./xfsslower Tracing XFS operations slower than 10 ms TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME 02:08:32 b'yum' 117971 S 0 0 14.36 b'Group' 02:25:55 b'yum' 118664 S 0 0 14.84 b'containernetworking-plugins-1.4.' 02:26:51 b'ldconfig' 119683 S 0 0 34.16 b'ld.so.cache~' 02:26:51 b'yum' 118664 S 0 0 11.01 b'packages.db-journal' TIME - 时间戳 COMM - 执行文件操作的进程名 PID - 进程的PID T - 操作类型(R=读,W=写,S=同步等) BYTES - 操作涉及的数据量大小(单位:字节) OFF_KB - 文件内的偏移量(单位:千字节,KB) LAT(ms) - 操作耗时 FILENAME - 被操作的文件路径或名称
biolatency追踪块设备延迟 biolatency工具跟踪块设备I/O(磁盘I/O),记录I/O时延(时间)的分布。按下Ctrl+C键结束跟 踪,生成直方图并显示在终端上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ./biolatency Tracing block device I/O... Hit Ctrl-C to end. usecs : count distribution 0 -> 1 : 0 | | 2 -> 3 : 0 | | 4 -> 7 : 0 | | 8 -> 15 : 0 | | 16 -> 31 : 0 | | 32 -> 63 : 1 |* | 64 -> 127 : 0 | | 128 -> 255 : 11 |****************** | 256 -> 511 : 24 |****************************************| 512 -> 1023 : 19 |******************************* | 1024 -> 2047 : 1 |* | 2048 -> 4095 : 1 |* | 4096 -> 8191 : 17 |**************************** | usecs(延迟区间)延迟时间范围,单位是微秒(μs)。 count(计数)该延迟区间内发生的 I/O 操作次数。 distribution(分布直方图)用星号(*)直观展示各区间操作次数的比例,越长表示次数越多。
biosnoop查看块设备IO情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ./biosnoop TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms) 0.000000 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.28 2.048004 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.33 4.095876 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.21 4.354287 kworker/u8:3 38 sda W 58324592 4096 2.59 6.143810 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.20 8.192088 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.37 10.240044 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.36 12.287971 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.33 14.335888 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.23 16.383926 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.29 TIME(s):工具启动后0秒时触发的操作。 COMM:内核工作线程 kworker/0:2。 PID:进程 ID 为 122248。 DISK:目标磁盘未知(可能是虚拟设备或元数据操作)。 T:读操作R,写操作W。 SECTOR:扇区号 BYTES:传输了 8 字节。 LAT(ms):操作耗时,单位毫秒。
cachestat跟踪内核页缓存函数—热点分析 cachestat工具跟踪内核页缓存函数,并以每秒的速度打印摘要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ./cachestat HITS MISSES DIRTIES HITRATIO BUFFERS_MB CACHED_MB 0 137824 0 0.00% 1620 1379 830 101376 0 0.81% 1725 1283 99 102400 0 0.10% 1817 1196 0 103034 0 0.00% 1886 1115 256 101376 0 0.25% 1957 1046 0 99529 0 0.00% 2010 992 671 98304 0 0.68% 2041 960 测试命令: dd if =/dev/sda2 of=/dev/nullHITS:缓存命中次数; MISSES:缓存未命中次数; DIRTIES:加入缓存脏页数; RATIO:缓存命中率; BUFFERS_MB:buffers大小,单位:MB; CACHED_MB:cache大小,单位:MB;
gethostlatency追踪解析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ./gethostlatency TIME PID COMM LATms HOST 04:56:00 122371 ping 9.82 baidu.com 04:56:05 122372 ping 1.71 google 04:56:07 122373 ping 8.55 google.com 04:57:07 122374 isc-worker0000 0.02 127.0.0.1 04:57:07 122374 isc-worker0000 0.01 ::1 04:57:18 122379 isc-worker0000 0.01 127.0.0.1 04:57:18 122379 isc-worker0000 0.01 ::1 TIME 操作触发的时间(时:分:秒) PID 发起主机名解析的进程 ID COMM 进程名称(例如 ping、isc-worker0000) LATms 主机名解析的延迟,单位:ms HOST 进程尝试解析的目标主机名或 IP 地址