开源工具学习记录之流程梳理
近期对腾讯的的开源项目: nettrace(网络故障分析工具) ,进行源码学习。
开源仓库:Nettrace开源仓库
开源工具实现注释:nettrace学习记录
Nettrace工具学习记录之流程梳理
nettrace工具在编译成功后,会生成nettrace可执行文件,当我们通过传参使用该工具时,会经历以下4个阶段,分别是准备阶段、数据采集阶段、数据处理阶段、数据分析阶段。
初步介绍一下nettrace整体流程:
- 当用户通过参数控制启用nettrace某一功能后(开启某模式)后,首先会进入准备阶段,该阶段会构建trace tree、通过解析参数设置跟踪模式、根据确定的跟踪模式启用对应的跟踪点(这里涉及到了BPF程序自动挂载技术);
- 当确定了启用哪些跟踪点后,将会进入到内核数据采集阶段,在该阶段,会根据启用跟踪点自动生成的BPF程序来对内核数据进行过滤与采集(这里涉及到BPF程序自动生成技术),并将采集到的数据传输到Perfbuffer中,等待用户态数据处理模块对其进行处理;
- 在数据采集阶段采集到内核数据并传输至Perfbuffer中后,将会根据对应的跟踪模式触发对应的数据处理模块,将收到的数据进行数据处理与输出;
- 对于大部分的跟踪点,都定义了所对应的数据分析器,如果需要,会进入数据分析器进行数据分析;

1.数据采集流程梳理
1.1 参数控制->准备阶段
用户在通过字符串界面输入传参后, 会执行以下步骤:

- 1.首先会进入准备阶段,该阶段会根据构建跟踪点组也即图中的trace树;

-
2.在将nettrace项目所涉及到的所有跟踪点构建成树后,会将用户的传参进行解析,来确定跟踪模式(该项目提供了八种跟踪模式,不同的跟踪模式所使用到的跟踪点以及数据处理方式均不相同);
-
3.在确定了跟踪模式后会根据跟踪模式在trace树中启用相关的跟踪点;

1.2 准备阶段->数据采集
经过准备阶段将trace树、跟踪模式、要启用的跟踪点设置完毕后;将进行数据采集阶段,在数据采集部分,会根据跟踪模式及挂载的跟踪点,进行数据收集和数据过滤,并将数据传输至perfbuffer处;

-
1.BPF程序自动生成:对于传统的ebpf程序,会对每个跟踪点定义其数据收集数据过滤逻辑;而nettrace则是通过定义了三个宏,分别是
KPROBE_DEFAULT、TP_DEFAULT、FNC,分别对应默认的使用kprobe挂载的跟踪逻辑、默认使用tracepoint挂载的跟踪逻辑、以及自定义的跟踪逻辑,大部分跟踪点均使用默认的跟踪逻辑(也就是前两个宏定义的逻辑),极少数使用了FNC来自定义数据收集逻辑;我们将KPROBE_DEFAULT、TP_DEFAULT宏分别展开来探究两个默认数据采集的逻辑:- 默认tracepoint跟踪点将会执行以下数据采集逻辑,(仅以napi_gro_receive_entry跟踪点为例)
static __always_inline int fake__napi_gro_receive_entry(context_info_t *info); SEC("tp_btf/napi_gro_receive_entry") int trace_napi_gro_receive_entry(void **ctx) { context_info_t info = { .func = INDEX_napi_gro_receive_entry, .ctx = ctx, .args = (void *)CONFIG(), .skb = ctx_get_arg(ctx, 3) }; if (pre_handle_entry(&info, INDEX_napi_gro_receive_entry)) return 0; handle_entry_finish(&info, fake__napi_gro_receive_entry(&info)); return 0; } static __always_inline int fake__napi_gro_receive_entry(context_info_t *info) { return default_handle_entry(info); }- 默认kprobe相关跟踪点将会执行以下数据采集逻辑(仅以dev_gro_receive跟踪点为例)
static __always_inline int fake__dev_gro_receive(context_info_t *info); SEC("kretprobe/dev_gro_receive") int trace_ret_dev_gro_receive(struct pt_regs *ctx) { return handle_exit(ctx, INDEX_dev_gro_receive); } SEC("kprobe/dev_gro_receive") int trace_dev_gro_receive(struct pt_regs *ctx) { context_info_t info = { .func = INDEX_dev_gro_receive, .ctx = ctx, .args = (void *)CONFIG(), .skb = nt_ternary_take(1, ctx_get_arg(ctx, 1), NULL), .sk = nt_ternary_take(, ctx_get_arg(ctx, ), NULL) }; if (pre_handle_entry(&info, INDEX_dev_gro_receive)) return 0; handle_entry_finish(&info, fake__dev_gro_receive(&info)); return 0; } static __

最低0.47元/天 解锁文章
734

被折叠的 条评论
为什么被折叠?



