需求
假设我现在有一个进程,是周期运行,比如10ms执行一次。
在运行过程中,可能会有系统调用,比如读写一些文件。或者打印一些log到终端。
中间可能会被中断打断,也可能被RT进程抢占。
我需要实时将每一次运行的时长和开始执行的时间周期通过网络协议发送到远端的设备上,进行监控和显示。
如果我做着做着发现我水平还行的话,可能会加入检测进程被谁打断,在等什么资源这样一些帮助分析问题的信息。
下面就对需求进行分类和分级了:
必须实现的需求
【Req1】获取 服务使用者调用服务,到进入服务处理程序的时间。
【Req2】获取 线程工作代码入口到返回结果的时间差。
【Req3】周期地分析数据,将数据进行统计分析,比如一千次执行。后得出一个汇总的结果。
【Req4】数据按照一定的格式,按一定周期发送到网络设备上。
方案设计
针对必须实现的需求
【Req1】获取 服务使用者调用服务,到进入服务处理程序的时间。
对于周期轮询的线程,这个需求可能没什么意义。可以视为从周期到来到进入代码的时间?如果变成了测调度器性能意义不大。
对于服务器客户端架构的系统。可以在客户调用服务的时候打下时间戳,在服务程序入口处再打下时间戳。
如何实现一个全局的时间监控,可能必须使用类型LTTng的Trace功能。
不然可能需要将程序内记录的时间数据通过接口传输给服务程序。来进行一个计算。
这里我当然是选择使用LTTng 的方式来尝试实现这个功能。
从记录内核和用户程序的角度入手思考:
对内核来说,可以记录的是:
lttng enable-event --kernel sched_switch,sched_process_fork
lttng enable-event --kernel --syscall open,close
可能注意侧重于调度跳转和开新线程。对于资源可以监控一下读写系统调用。
因为是对应用程序的监控。实践上还是通过添加用户空间的Trace Point来实现:
方法一: 在代码中添加TracePoint。可以通过直接定义tracepoint,tracepoint class来实现。
方法二:Load a prebuilt user space tracing helper。链接提供的库,通过编译指令加-finstrument-functions来监控程序出入口。
【Req2】获取 线程工作代码入口到返回结果的时间差。
和上一个需求类似。
可以用LTTng 的用户程序tracepoint.
除此之外 ,使用steady_clock自己开发应该也说得过去。
【Req3】周期地分析数据,将数据进行统计分析,比如一千次执行。后得出一个汇总的结果。
需要周期性的将数据拉出来进行分析。有两种实现方式:
- 使用relayd的方式,LTTng Live。来实时拉出数据。然后在嵌入式设备中部署一个Agent线程。接收统计这些数据。
- 使用Trigger的方式。定时停止record写一份数据,比如可以设计事件捕捉了一千个。然后直接分析trace log。
这一步涉及到babeltrace2
。这个LTTng自己做的工具。
【Req4】数据按照一定的格式,按一定周期发送到网络设备上。
简单来讲,可以通过UDP发数据。
或者socket编程。
或者其他随便什么协议。