作者:手机用户2502873667 | 来源:互联网 | 2023-06-13 19:20
闲聊几句用erlang有1年有余,也是第一次接触函数式编程,主要用于编写性能测试工具,在使用初期问题较少,遇到问题我仍习惯性通过debug来解决,勉强能用,但是随着系统复杂性增加,
闲聊几句
用erlang有1年有余,也是第一次接触函数式编程,主要用于编写性能测试工具,在使用初期问题较少,遇到问题我仍习惯性通过debug来解决,勉强能用,但是随着系统复杂性增加,多线程运行时debug就显得难上加难,这是和之前面向过程编程有本质区别。
之后结识了dbg trace,很强大的工具,可以很方便地分析系统执行过程中的情况,但是相比较而言我会更推荐recon_trace这个工具,该工具是程序员里漫画画的最好的Fred写的,同时也是<>的作者。
初识recon_trace
recon_trace绝对是协助你定位线上问题的一把利器,目前只支持trace函数调用,基本够用了。工具基于erlang:trace进行了二次封装,特性如下:
- 调用更友好,比起dbg:trace()和erlang:trace()更好用
- 防止用户trace信息过多引起系统崩溃,比如trace当前节点所有进程的函数调用信息
- 提供maxcount,maxfre参数,防止flooding
- 输出信息格式优化
小试牛刀
先来试试trace 任意进程对queue:new的调用
注意最后那个参数,1就是maxcount参数,它决定了最多trace信息的数量,防止tracce flooding。
1> recon_trace:calls({queue, new, ‘_’}, 1).
1
2> queue:new().
{[],[]}
3>
22:26:54.646000 <0.55.0> queue:new()
3> Recon tracer rate limit tripped.
3>
返回值去哪了
我们如果想获取调用函数的返回值需要return_trace的帮助,如下:
6> recon_trace:calls({queue, new, fun(_) -> return_trace() end}, 2).
1
7> queue:new().
22:45:09.098000 <0.55.0> queue:new()
22:45:09.098000 <0.55.0> queue:new/0 –> {[],[]}
{[],[]}
Recon tracer rate limit tripped.
本实例中除了return_trace需要添加外,maxcount的数量你也可以尝试改为1,试试看,你会对maxcount有更深的认识
来个更复杂的
when语句限定了只trace属于queue模块的函数的调用,且第一个函数参数为列表或第一个参数为大于1的数字。另外请注意最后一个tuple参数,这个参数可以理解为maxfreq,即trace信息的最大频率,{10,100}表示100毫秒内做多打印10条trace信息。这算是防止flooding的另外一种策略。
recon_trace:calls(
{queue, '__', fun([A,_]) when is_list(A); is_integer(A) andalso A > 1 -> return_trace() end},
{10,100}
).
如何限定调用pid
有时我们只关注发生在特定进程的调用,那么就需要calls/3,在第三个参数可以指定附加参数信息,还有其他附加参数,这里不一一列出,可以看官方文档,或者索性直接源码。
recon_trace:calls({queue, '_', '_'}, {50,1000}, [{pid, Pid}])
如何停止trace
recon_trace:clear()