HACK#75 运用SystemTap
本节介绍在实际系统上运用SystemTap的方法。
SystemTap是优秀的追踪工具。除了作为工具以外,作为服务也具有十分优秀的功能。具有作为服务启动的后台执行模式,也具有作为系统服务管理的接口。另外,在集群(cluster)环境想要重新分配相同脚本时,也可以分配已编译的脚本。
在后台执行SystemTap
下面将介绍SystemTap的后台执行模式。SystemTap的后台执行,有内存飞行记录器模式(on memory flight mode)和文件飞行记录器模式(on file flight mode)这两个模式。前者是将输出结果保存在内核内存上的模式,使用方法与不断提取最新记录的飞行记录器或行车记录器(drive flight)相同。后者是在后台将输出结果写出到磁盘上的模式,适用于长期提取记录的系统监测方法。
为了介绍这个功能,实际编写SystemTap的脚本syscalltop.stp,它按照系统调用的种类分别显示每5秒钟执行系统调用的次数。
global syscalls, stime;
probe syscall.*{
stime[name, tid()]=gettimeofday_us();
}
probe syscall.*.return{
if(!stime[name, tid()])
next;
syscalls[name]<<<(gettimeofday_us()-stime[name, tid()]);
delete stime[name, tid()];
}
probe timer.s(5){
println("<name>\t<count>\t<avgtime(us)>—-");
foreach(name-in syscalls){
printf("%s\t%d\t%d\n",name,
@count(syscalls[name]),@avg(syscalls[name]));
}
delete syscalls
}
下面是使用这个脚本执行飞行记录器的例子。
首先尝试将输出结果保存在内存上的内存飞行记录器模式。使用这个模式时需要向stap命令传递-F选项来启动。启动时使用-m决定脚本模块名称,后面的控制就会比较容易。另外还可以使用-s(小写)选项指定保存日志的缓冲区容量。缓冲区容量在启动后就无法更改,因此必须在这时指定最适合的容量。
stap syscalltop.stp-m syscalltop-F
Disconnecting from systemtap module.
To reconnect, type"staprun-A syscalltop"
lsmod|head
Module Size Used by
syscalltop 800448 0
ip6table_filter 1759 0
ip6_tables 19857 1 ip6table_filter
ipt_MASQUERADE 1927 3
iptable_nat 4430 1
nf_nat 18833 2 ipt_MASQUERADE, iptable_nat
nf_conntrack_ipv4 13057 4 iptable_nat, nf_nat
nf_defrag_ipv4 1609 1 nf_conntrack_ipv4
xt_state 1394 1
在内存飞行记录器模式下运行时,就会返回如上所示的提示(prompt)。但是从lsmod的结果可以看出,从syscalltop脚本生成的脚本模块在内核中不断运行。要确认syscalltop.stp的输出结果时,如界面输出所示执行staprun-A syscalltop。
staprun-A syscalltop
<name><count><avgtime(us)>—-
writev 5 7
write 11 16
wait4 2 6990840
tgkill 5 5
stat 1 722
setitimer 4 3
select 12 3295040
rt_sigtimedwait 2 6988895
……
即使不指定-F选项,在运行中也可以按下Ctrl+\或向stapio进程发送SIGQUIT信号,同样切换到内存飞行记录器模式。
接下来尝试将输出结果写出到文件的文件飞行记录器模式。这个模式与刚才的模式同样可以使用-F选项,再指定-o选项,指定写出到的文件。这样的话文件的大小就会逐渐变大,对磁盘容量造成压力,因此可以使用-S选项来避免。-S选项可以指定文件的最大大小和最大文件数量。写出到的文件容量一旦超过-S选项指定的量,SystemTap就会打开另一个文件,并开始在这个文件中写出。这样不断增加的文件数量一旦超过-S选项指定的最大数量,就会从最旧的文件开始删除。
进行这样的后台执行时,为了减少运行时的系统开销,可以启用-b选项并启用bulk模式。启用bulk模式后,SystemTap就会在每个CPU上分配缓冲区,并记录追踪信息。向文件写出时,也会在每个CPU上创建线程,向其他文件写出。这样就可以防止数据记录时的竞争,因此系统开销就会减小。
-o选项可以向输出文件的名称指定strftime()函数形式的格式。在下例中,将前面所述的syscalltop脚本在文件飞行记录器模式下启动,并将追踪日志输出到名称为tracelog-年-月-日-时:分:秒.log的文件。另外,输出文件的最大大小设置为256MB,只留下最新的两个日志。
stap syscalltop.stp-m syscalltop-F-o tracelog-%F-%T.log-S 256,2
2565
ps aux|grep 2565
root 2565 0.2 0.0 47244 596?Ssl 16:33 0:00/usr/
lib/systemtap/stapio-o syscalltop-%F-%T.log-D-S 256,2/tmp/stapSyNXqX/
syscalltop.ko
……
ls tracelog*
tracelog-2011-04-17-16:33:14.log.0
在文件飞行记录器模式下启动stap命令时,会在命令结束前显示一直在后台运行的进程的PID。通过向这个PID发送信号,进行后台进程的控制。例如,如果发送SIGUSR2信号,就会切换正在写出的文件(参考下例),发送SIGQUIT信号就可以从文件飞行记录器模式转换到内存飞行记录器模式。想要结束运行时可以发送SIGTERM信号。
ls tracelog*
tracelog-2011-04-17-16:33:14.log.0
kill-USR2 2565
ls syscalltop*
tracelog-2011-04-17-16:33:14.log.0
tracelog-2011-04-17-16:35:03.log.1