systemtap学习记录一
前两天拜读了章亦春大佬的关于Dynamic Tracing的文章,觉得对现在碰到的一些问题有了一些新的思考,为了能有所产出就先写一点简单的学习记录
首先这个systemtap类似于一个linux系统层面的探针工具,可以让用户去监控系统的各种活动
以阿里云的 ubuntu 22.04 为例,
首先我们需要安装 systemtap-sdt-dev
这个包,
然后因为通过c的方式比较常规,我是想研究下针对像 php 这种怎么去监控
我们需要一个编译参数带上--enable-dtrace
的php版本
然后在编译完后我们写一个简单的测试脚本1
2
3
4
5
6
function a($b, $c) {
return $b + $c;
}
sleep(1);
echo a(1, 2);
这其实主要是为了触发系统调用
然后重点就是systemtap的脚本,它有点类似于c的代码,结构主要是 “事件” - “处理器”
比如我监听到了php发起了一个系统调用,那这个时候我想把它记录下来,打印日志这种1
2
3
4
5
6probe syscall.*
{
if (execname() == "php") {
printf ("%s(%d) open, call %s \n", execname(), pid(), name)
}
}
这里就是针对所有的系统调用,如果是由php发起调用,那就打印出来pid和系统调用的名字(name就是这里的系统调用名字)
事件
syscall.system_call
只是其中一类事件
还有对虚拟文件系统的操作 vfs.file_operation
内核的方法调用 kernel.function("function")
比如 probe kernel.function("*@net/socket.c") { }
还有可以是内核的一些追踪点kernel.trace("tracepoint")
比如 kernel.trace("kfree_skb")
这个表示每次当内核中的network buffer被释放的时候触发
还有的是时间时间timer events
比如1
2
3
4probe timer.s(4)
{
printf("hello world\n")
}
每4秒打印一个 hello world
还有这些1
2
3
4
5timer.ms(milliseconds)
timer.us(microseconds)
timer.ns(nanoseconds)
timer.hz(hertz)
timer.jiffies(jiffies)
处理器
最常规的一类就是打印信息了printf ( ) Statements
这个跟c语言也很像,可以用%s
跟 %d
作为占位符来填充字符串和数字
然后就是一些定义好的取值方法execname() (a string with the executable name)
就比如刚才的php,
线程id1
2tid()
The ID of the current thread.
用户id1
2uid()
The ID of the current user.
比如系统调用就直接用 name
还有很多可以研究,第一篇学习就先到这里