使用bpftrace监测libcurl的执行时长

本文详细介绍了如何使用bpftrace工具监控程序通过libcurl发起的网络请求,包括设置脚本、动态库路径查找和关键函数跟踪,旨在帮助读者理解并实操这种强大的系统级监控技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bpftrace的使用网上没有太多的说明;皮毛都算不上,都是介绍这个东西是啥,连个有用的实例也没有,没有啥参考意义,不如直接看看官方的文档;

我这里给一个干货,比如你的程序调用了libcurl访问网页,检测一下用了多久;

bt监控脚本教程见官方:bpftrace/reference_guide.md at master · iovisor/bpftrace · GitHub

脚本如下:(保存为  t.bt )


BEGIN 
{ 
    @start = nsecs; 
}


uprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_setopt
{
    if (arg1 == 10002)
    {
    	printf("seturl pid=%d, tid=%d, url=%s\n", pid, tid, str(arg2));
    }
    
}

uprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_perform
{
 
   printf("enter  pid=%d, tid=%d, process=%s\n", pid, tid, comm);
   @start = nsecs;
}

uretprobe:/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_perform
{
   printf("finish pid=%d, tid=%d, cost=%d ms\n", pid, tid, (nsecs - @start)/1000000);
   
}

使用过程中,需要注意的是:

1)对监控的进程需要执行ldd查看动态库所在的路径,而不是直接写进程可执行程序路径:

ldd  exe_name

2)curl设置url中的参数,需要根据第2个参数来判断;

另一个bash窗口启动需要监控的进程,此窗口执行脚本等待输出;

输出的结果为:

备注:题外话,在c++的程序编译后,我们见到的符号名字(ABI)不一定是原来的样子,只有C风格的接口才会保持原来的样子,那么改如何对应原来的的名字呢?答案是使用c++filt工具,翻译程序中的符号的命令如下:


nm -l icmp | grep "Icmp" | c++filt

1)icmp是我写的程序名;

2)Icmp是其中的类名,过滤相关的类,

可以看到原来的名字,这样我们就可以将监控的符号名与原始名字对应起来了;

输出如下:

00000000000375a8 T IcmpWorker::preSortUrl(std::shared_ptr<oneapm::Info>&)	/robin1/ct_agent/src/IcmpWorker.cpp:173
00000000000372d4 T IcmpWorker::curl(std::shared_ptr<oneapm::Info>&)	/robin1/ct_agent/src/IcmpWorker.cpp:145
0000000000036bd8 T IcmpWorker::init()	/robin1/ct_agent/src/IcmpWorker.cpp:14
0000000000036c00 T IcmpWorker::ping(std::shared_ptr<oneapm::Info>&, int)	/robin1/ct_agent/src/IcmpWorker.cpp:21
0000000000036f88 T IcmpWorker::trace(std::shared_ptr<oneapm::Info>&)	/robin1/ct_agent/src/IcmpWorker.cpp:83
0000000000037a54 T IcmpWorker::doWork(std::shared_ptr<oneapm::Info>&)	/robin1/ct_agent/src/IcmpWorker.cpp:238
0000000000036afe T IcmpWorker::IcmpWorker()	/robin1/ct_agent/src/IcmpWorker.cpp:5
0000000000036afe T IcmpWorker::IcmpWorker()	/robin1/ct_agent/src/IcmpWorker.cpp:5
0000000000036bae T IcmpWorker::~IcmpWorker()	/robin1/ct_agent/src/IcmpWorker.cpp:9
0000000000036b6a T IcmpWorker::~IcmpWorker()	/robin1/ct_agent/src/IcmpWorker.cpp:9
0000000000036b6a T IcmpWorker::~IcmpWorker()	/robin1/ct_agent/src/IcmpWorker.cpp:9

但是,在c++中获取参数更加麻烦,主要是因为参数很多并非基础类型或者基础类型指针,有可能是类的引用,比如某成员函数如下:

void Icmp::executeTask(string & name, Task & task)
{
}

这个,我也没有想明白怎么提取呢,如果你知道,希望也告诉我。

待续……

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值