[Erlang_Question31]Erlang trace总结

在一个并行的世界里面,我们很难做到单步断点调试来定位问题(太多的消息飞来飞去),Erlang设计者也深刻体会到这一点,推出了另一个trace机制。

通过这个trace,你可以:

1.指定进程内的函数调用输入输出,收发消息;
2.指定端口的输入输出,收发消息。

这样你就可以不加一行代码(抛弃那类io:format的烦琐又单一的方法吧),不影响正常运行的系统来(在一个服务器系统里面单步断点几乎是不可行的),就查看到你想要了解的控制流程。

现在Erlang用于Trace的库有:

sys  comes standard with OTP and allows to set custom tracing functions, log all kinds of events, and so on. It’s generally complete and fine to use for development. It suffers a bit in production because it doesn’t redirect IO to remote shells, and doesn’t have rate-limiting capabilities for trace messages. It is still recommended to read the documentation

for the module.

dbg  also comes standard with Erlang/OTP. Its interface is a bit clunky in terms of usability, but it’s entirely good enough to do what you need. The problem with it is that you have to know what you’re doing, because dbg can log absolutely everything on the node and kill one in under two seconds.

tracing BIFs are available as part of the erlang module. They’re mostly the raw blocks used by all the applications mentioned in this list, but their lower level of abstraction makes them rather difficult to use.

redbug  is a production-safe tracing library, part of the eper 5 suite. It has an internal rate-limiter, and a nice usable interface. To use it, you must however be willing to add in all of eper’s dependencies. The toolkit is fairly comprehensive and can be a very interesting install.

recon_trace  is recon’s take on tracing. The objective was to allow the same levels of safety as with redbug, but without the dependencies. The interface is different, and the rate-limiting options aren’t entirely identical. It can also only trace function calls, and not messages.

• sys 是一个标准的OTP, 可以允许自 定义trace函数, 记录所有类型的事件等等。 它非常完善且可以很好地用于开发。 但它会稍微影响处于生产 环境的系统, 因为它没有把IO重定向到远程的shell中, 而且他没有限制trace消息的速度。 不过还是推荐阅读其文档模块。

dbg 也是一个标准的OTP。 它的接口在可用性方面显得有点笨拙。 但它完全足以满足你所需。 问 题在于: 你必须要知道你要做什么,因为 dbg可以记录一切, 并在2秒内把系统搞崩溃。

tracing BIFs作为一个Erang的模块可用。 它们大多作为原始块(the raw blocks)由这个列表中提到的application所调用,但由于他们处于较底层, 比较抽象, 用起来也非常困难。

redbug 是可以在正式的生产 运行系统中使用的trace库, 是eper 的一部分, 它内部有一个速度限制开关, 和一个不错

的可用接口。 为了使用它, 你必须把eper的所有依赖项都加上。 这个工具箱非常全面, 你会体验到一次非常有趣的安装。

recon_trace 是recon中负 责trace的模块。 目 的是和redbug有相同的安全水平,但却不要这么多的依赖项。 接口也不一样, 速度限制选项并不完全相同。 它可以只trace指定的函数调用, 没有trace send/recv message (实际在使用OTP的application里面根本没有必要支持trace message这种机制)

想要把上面的trace工具用起来,必须要掌握的基本概念。

我们要给trace指定目标:

1. 指定trace的进程集;
2. 指定模块中指定的函数的指定入参。

这两个加起来就的交集就是要trace的集合。

%%%         _,--------,_      _,--------,_
%%%      ,-‘            `-,,-‘            `-,
%%%   ,-‘              ,-‘  ‘-,              `-,
%%%  |   Matching    -‘        ‘-   Matching    |
%%%  |     Pids     |  Getting   |    Trace     |
%%%  |              |   Traced   |  Patterns    |
%%%  |               -,        ,-               |
%%%   ‘-,              ‘-,  ,-‘              ,-‘
%%%      ‘-,_          _,-‘‘-,_          _,-‘
%%%          ‘--------‘        ‘--------‘
%%% 

接下来以最常用的dbg库来说明上面的这两个交集规则,其它库也是类似于此。


1.先从指定模块,函数,和参数开始:

> dbg:start().   % start dbg
> dbg:tracer().  % start a simple tracer process
> dbg:tp(Module, Function, Arity, []).   % specify MFA you are interested in
> dbg:p(all, c).   % trace calls (c) of that MFA for all processes.

... trace here

> dbg:stop_clear().   % stop tracer and clear effect of tp and p calls.

你可以使用tp同时trace多个函数,如果你想trace模块中没有导出的函数,请使用tpl,

如果想移除trace就使用ctp或ctpl

> dbg:tpl(Module, ‘_‘, []).  % all calls in Module
> dbg:tpl(Module, Function, ‘_‘, []).   % all calls to Module:Function with any arity.
> dbg:tpl(Module, Function, Arity, []). % all calls to Module:Function/Arity.
> dbg:tpl(M, F, A, [{‘_‘, [], [{return_trace}]}]).   % same as before, but also show return value.

你可以使用dbg:fun2ms来生成函数入参的匹配模式。

1> dbg:fun2ms(fun([M,N]) when N > 3 -> return_trace() end).
[{[‘$1‘,‘$2‘],[{‘>‘,‘$2‘,3}],[{return_trace}]}]

2.你可以使用dbg:p函数来指定特定的进程:

> dbg:p(all, c).   % trace calls to selected functions by all functions
> dbg:p(new, c).   % trace calls by processes spawned from now on
> dbg:p(Pid, c).   % trace calls by given process
> dbg:p(Pid, [c, m]).  % trace calls and messages of a given process

dbg里面的函数都是对erlang:trace的封闭,erlang:trace太底层,接口非常难用,所以就封闭成了dbg库。

使用dbg要注意:

1.由于trace时产生的日志非常多,通常需要把它放到一个文件汇总后再分析(而不是直接输出到shell中):

生成多个文件保存日志:

>dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node())})).

这点也说明了dbg太放纵使用者,一不小心就会产生大量的日志,导致节点异常。生产环境中慎用。

2.所有的tp,p都是在在dbg:start/0,dbg:trace/0开启后才能起作用的。


从上面可以看出:dbg把过滤进程,过滤{Module,Fun,Arity}分开处理。当然这样更加灵活,控制更精确。

但有那么一群人觉得dbg还不是很完善:

1.接口太过复杂,使用步骤复杂:start----》自定义的trace-----》stop;
2.没有输出日志次数控制,在生产环境中使用不当时会导致异常:不安全!

所以就有了上面介绍的redbug,recon_trace库。



下面介绍一下recon_trace库(他的使用是安全的!):

1.接口使用简单,他只需要调用一个函数calls/2 calls/3就可以trace;
2. 有次数限制和速度限制;
3.输出的trace比的默认的trace易读性强。

他把过滤进程集和模块函数过滤结合在一起啦!

calls/2 Equivalent to calls({Mod, Fun, Args},Max, []).

calls/3 Allows to set trace patterns and pid specifications to trace function calls.

clear/0 Stops all tracing at once.

这个库的接口都非常简单,用一次基本就上手啦,例子可以看这里


参考资料

1.http://stackoverflow.com/questions/1954894/using-trace-and-dbg-in-erlang

2.http://ferd.github.io/recon/recon_trace.html

when i show tracing on a production node to


时间: 2024-11-03 21:50:08

[Erlang_Question31]Erlang trace总结的相关文章

erlang调试技术之etop

etop是erlang进程信息查看工具,类似于UNIX的top. 一.配置参数 node The measured node. Value: atom() Mandatory setcookie Cookie to use for the etop node - must be the same as the cookie on the measured node. Value: atom() lines Number of lines (processes) to display. Value

Erlang generic standard behaviours -- gen_server system msg

这是Erlang generic standard behaviors gen_server 分析的系列的最后一篇,主要分析gen_server module 辅助性的功能函数. 在gen_server 的MAIN loop 流程中,除了处理Parent 的'EXIT' 消息, user module 常规消息之外, 还处理了一类 system 消息. 这一类system 消息的来源是一个sys 的module,在Erlang OTP体系中,sys module 主要有两大类的作用,一个是热更,

启动erlang/OTP里面的Web服务器(application INETS启动过程代码分析)

上两篇分别用两种方式启动了inets中的httpd,其实本质一样的:下面简单分析一下过程,函数粒度的介绍. 1,下面是application inets的代码目录,虽然ftp.tftp.http_client.http_lib.http_server.inets_app在这目录中并列,其实inets_app扮演顶层控制角色: 只有inets_app是一个application,而其他都是module---application的一部分并且需要application启动和管理. [[email p

erlang send剖析及参数意义

erlang send是一个很基础的消息发送函数,用于进程把一个消息发给另外一个进程.这个函数可以同时用于本地节点进程通信,或者和远程节点进程之间的通信. 前言 最近有同事遇到erlang:send导致消息堆积问题,这个引起了我的强烈关注.我也看了这块的代码,这里简单做个分享. 函数原型: erlang:send(Dest, Msg, Options) -> Res Options可以是以下2个: nosuspend If the sender would have to be suspende

Erlang generic standard behaviours -- gen

在分析 gen_server (或者是gen_fsm )之前,首先应该弄明白,gen 这个module . 1 -module(gen). 2 -compile({inline,[get_node/1]}). 3 4 %%%----------------------------------------------------------------- 5 %%% This module implements the really generic stuff of the generic 6 %

64位CentOS6.2安装erlang及rabbitmqServer

CentOS 6.2 64bit 安装erlang及RabbitMQ Server 1.操作系统环境(CentOS 6.2 64bit) 1 [[email protected] ~]# cat /etc/issue 2 3 CentOS release 6.2 (Final) 4 Kernel \r on an \m 5 [[email protected] ~]# cat /proc/cpuinfo |grep "clflush size" 6 clflush size : 64

[Erlang危机]Erlang In Danger 序言

原创文章,转载请注明出处:服务器非业余研究http://blog.csdn.net/erlib 作者Sunface?? Introduction On Running Software 运行时软件 There's something rather unique in Erlang in how it approaches failure compared to most other programming languages. There's this common way of thinkin

erlang catch的内部实现(初稿)

最近项目组有同事做了erlang内部数据(Eterm)的分享.Eterm 是Erlang Term的简写,用来表示erlang中任意类型的数据,也就是说,erlang可以用到的任意数据,都能 Eterm表示.比如常见的atom.数字.列表.元组,甚至pid,port,fun,ets表等等都用Eterm可以表示. Eterm Eterm 在VM中主要分为三大类:列表,boxed对象,立即数.(这么分法主要是复杂的数据无法单靠1个机器字表示) 其中,boxed对象表示了复杂数据类型,如元组,大整数,

Erlang学习笔记2

http://wgcode.iteye.com/blog/1007623 第二章 入门 1.所有的变量都必须以大写字母开头,如果要查看某个变量,只要输入变量的名字即可,如果一个变量被赋予值,就称为绑定变量,否则被称为自由变量,一开始所有变量都是自由的. 有一点像Java中的常量,这就是为什么用大写字母的原因. 2.  “=” 近似于一个赋值操作符,是一个模式匹配运算符,当X是自由变量未被赋值时“=”是赋值运算符,否则是模式匹配运算符. 3. “/”除号永远返回浮点数. 4. 原子用来表示不同的非