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