非常教程

Erlang 20参考手册

et

2. Tutorial

2.1可视化消息序列图

最简单的使用方法ET是将其用作显示消息顺序图的图形工具。为了做到这一点,你需要首先启动一个Viewer(默认启动一个Collector):

{ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
CollectorPid = et_viewer:get_collector_pid(ViewerPid).

然后将事件发送到Collector有功能et_collector:report_event/6就像这样:

et_collector:report_event(CollectorPid,85,from,to,message,extra_stuff).

Viewer会自动将事件从Collector屏幕上拉出并显示出来。

数字(在本例中为85)是一个从1到100的整数,用于指定消息的“详细程度”。数字越高,它越重要。这提供了粗略的优先级过滤形式。

from,,,to,和message参数和它们听起来完全一样。fromtoViewer作为“生命线”,信息从一个传递到另一个。如果fromto都是相同的值,然后将其显示在生命线旁边,作为“动作”。大extra_stuff值是您可以附加的数据,当某人实际单击该操作或消息时,这些数据将显示在Viewer窗户。

模块et/examples/et_display_demo.erl说明如何使用它:

-module(et_display_demo).

-export([test/0]).

test() ->
    {ok, Viewer} = et_viewer:start([{title,"Coffee Order"}, {max_actors,10}]),
    Drink = {drink,iced_chai_latte},
    Size = {size,grande},
    Milk = {milk,whole},
    Flavor = {flavor,vanilla},
    C = et_viewer:get_collector_pid(Viewer),
    et_collector:report_event(C,99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
    et_collector:report_event(C,80,barrista1,register,enter_order,[Drink,Size,Flavor]),
    et_collector:report_event(C,80,register,barrista1,give_total,"$5"),
    et_collector:report_event(C,80,barrista1,barrista1,get_cup,[Drink,Size]),
    et_collector:report_event(C,80,barrista1,barrista2,give_cup,[]),
    et_collector:report_event(C,90,barrista1,customer,request_money,"$5"),
    et_collector:report_event(C,90,customer,barrista1,pay_money,"$5"),
    et_collector:report_event(C,80,barrista2,barrista2,get_chai_mix,[]),
    et_collector:report_event(C,80,barrista2,barrista2,add_flavor,[Flavor]),
    et_collector:report_event(C,80,barrista2,barrista2,add_milk,[Milk]),
    et_collector:report_event(C,80,barrista2,barrista2,add_ice,[]),
    et_collector:report_event(C,80,barrista2,barrista2,swirl,[]),
    et_collector:report_event(C,80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
    ok.

当您运行et_display_demo:test().函数在上面的示例中,Viewer窗口将如下所示:

图2.1:查看器窗口的屏幕截图

2.2四模

事件跟踪器框架由四个模块组成:

  • et
  • et_collector
  • et_viewer
  • et_selector

此外,您可能希望熟悉dbg模块和可能seq_trace模块也是。

2.3事件跟踪器接口

et模块与其他模块不同。它包含一个名为et:trace_me/5这是一个根本不做任何有用的事情的函数。它的唯一目的是成为一个易于跟踪的函数。给它打电话可能是这样的:

et:trace_me(85,from,to,message,extra_stuff).

参数et:trace_me/5和...一样et_collector:report_event/6在前一章。这两种功能的最大区别在于它们的语义。第二个报告实际上是EventCollector当第一个原子什么也不做时,它只返回原子。hopefully_traced.以便使参数et:trace_me/5出现在Collector,则必须激活该函数的跟踪,并且Collector必须注册为Tracer在...Raw Trace Data...

Erlang跟踪是一堆痛苦的起因,涉及巧妙端口的相当复杂的知识,跟踪返回格式和专门的跟踪MatchSpecs(这实际上是他们自己的特殊类型的地狱)。追踪机制确实非常强大,但难以掌握。

幸运的是,有一种简单的方法可以开始跟踪et:trace_me/5函数调用。的想法是,您应该使用调用et:trace_me/5在你的计划中有有趣的信息的战略位置。然后你就开始Collector启用全局跟踪:

et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).

这将启动一个Collector,一Viewer并开始跟踪et:trace_me/5函数调用。大Raw Trace DataCollector控件在屏幕上显示它的视图。Viewer.您可以通过实现自己的数据定义自己的“视图”。Filter函数并将它们注册到Viewer...

2.4收藏家和浏览者

这两件作品是一致的。基本上,Collector接收Raw Trace DataEventset特定格式(定义于et/include/et.hrl)处理它。的Viewer询问Collector和显示数据的交互式表示。

你可能想知道为什么这些不只是一个模块。这Collector是一个通用的完整框架,允许进程“订阅” Events它收集的内容。一个人Collector可以服务几个Viewers。典型的情况是你有一种Viewer可以Events用一种风味Viewer形象化,另一种用另一种风味形象化它们。例如,如果您正在追踪基于文本的协议HTML(如(或Megaco/H.248)),则可以显示Events纯文本以及邮件的内部表示形式。Viewer只要符合协议之间的Collector/Viewer协议,该体系结构也允许您实现自己的程序。目前Viewers存在两种。那是旧的GS基于一个和新的基础wxWidgets。但如果你觉得它可以实现你自己的Viewer,例如可以显示Events为ASCII艺术或任何你觉得有用的东西。

Viewer默认情况下会创建一个Collector适合你。有了几个选项和一些配置设置,你可以开始收集Events

CollectorAPI还允许您将收集Events的文件保存到文件中,并在以后的会话中加载它们。

2.5选举人

这可能是整个系统中最核心的模块。et套房。大Collector需要“筛选器”来转换Raw Trace Data转换成它可以显示的“事件”。大et_selector模块提供默认的Filter和一些API调用来管理Trace Pattern...Selector提供实现以下功能的各种功能:

  • 转换Raw Trace Data变成适当的Event
  • 神奇地注意et:trace_me/5功能的痕迹,并做出适当的决定Events
  • 小心防止翻译Raw Trace Data两次
  • 管理Trace Pattern

Trace Pattern是基本上的元组module和一个detail level(可以是整数或原子最大为全部细节)。在大多数情况下,这Trace Pattern {et,max}已经足够。但是,如果你不希望任何运行时依赖,et你可以trace_me/5在某些模块中实现你自己的功能,并引用该模块Trace Pattern

的实例化过程中产生的指定模块。Viewer,到Collector它自动创建的信息,将其作为Trace Pattern,并最终深入到Selector...

您指定的模块将被传递(最终)为Selector默认值Filteret:trace_me/5函数调用的格式是硬编码的Filter

2.6如何把它组合在一起

Collector自动将自身注册为监听跟踪Events,因此,所有你需要做的就是让他们。

对于那些想要进行一般跟踪的人,请参阅dbg模块,了解如何跟踪您感兴趣的内容,并让它发挥它的魔力。如果您只想et:trace_me/5工作,请执行以下操作:

  • 创建一个Collector
  • 创建一个Viewer(这可以为你做第一步)
  • 打开并削减调试

模块et/examples/et_trace_demo.erl做到这一点。

-module(et_trace_demo).

-export([test/0]).

test() ->
    et_viewer:start([
        {title,"Coffee Order"},
        {trace_global,true},
        {trace_pattern,{et,max}},
        {max_actors,10}
      ]),
      %% dbg:p(all,call),
      %% dbg:tpl(et, trace_me, 5, []),
      Drink = {drink,iced_chai_latte},
      Size = {size,grande},
      Milk = {milk,whole},
      Flavor = {flavor,vanilla},
      et:trace_me(99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
      et:trace_me(80,barrista1,register,enter_order,[Drink,Size,Flavor]),
      et:trace_me(80,register,barrista1,give_total,"$5"),
      et:trace_me(80,barrista1,barrista1,get_cup,[Drink,Size]),
      et:trace_me(80,barrista1,barrista2,give_cup,[]),
      et:trace_me(90,barrista1,customer,request_money,"$5"),
      et:trace_me(90,customer,barrista1,pay_money,"$5"),
      et:trace_me(80,barrista2,barrista2,get_chai_mix,[]),
      et:trace_me(80,barrista2,barrista2,add_flavor,[Flavor]),
      et:trace_me(80,barrista2,barrista2,add_milk,[Milk]),
      et:trace_me(80,barrista2,barrista2,add_ice,[]),
      et:trace_me(80,barrista2,barrista2,swirl,[]),
      et:trace_me(80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
      ok.

贯穿上述各点,最重要的一点是:

  • 打开全局跟踪
  • 设置一个 Trace Pattern
  • 诉说dbg跟踪函数调用
  • 具体地告诉它跟踪et:trace_me/5功能

当您运行et_trace_demo:test()函数上,Viewer窗口看起来就像这个截图:

图2.2:查看器窗口的屏幕截图

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1