Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 616

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- Tutorial</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/et-1.4.4.2.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>Event Tracer (ET)</strong><br><strong>User's Guide</strong><br><small>Version 1.4.4.2</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="Introduction" expanded="false">Introduction<ul>
<li><a href="et_intro.html">
              Top of chapter
            </a></li>
<li title="Scope and Purpose"><a href="et_intro.html#id64170">Scope and Purpose</a></li>
<li title="Prerequisites"><a href="et_intro.html#id61234">Prerequisites</a></li>
<li title="About This Manual"><a href="et_intro.html#id61059">About This Manual</a></li>
<li title="Where to Find More Information"><a href="et_intro.html#id60052">Where to Find More Information</a></li>
</ul>
</li>
<li id="loadscrollpos" title="Tutorial" expanded="true">Tutorial<ul>
<li><a href="et_tutorial.html">
              Top of chapter
            </a></li>
<li title="Visualizing Message Sequence Charts"><a href="et_tutorial.html#id60778">Visualizing Message Sequence Charts</a></li>
<li title="Four Modules"><a href="et_tutorial.html#id57439">Four Modules</a></li>
<li title="The Event Tracer Interface"><a href="et_tutorial.html#id61823">The Event Tracer Interface</a></li>
<li title="The Collector and Viewer"><a href="et_tutorial.html#id56971">The Collector and Viewer</a></li>
<li title="The Selector"><a href="et_tutorial.html#id58113">The Selector</a></li>
<li title="How To Put It Together"><a href="et_tutorial.html#id62590">How To Put It Together</a></li>
</ul>
</li>
<li id="no" title="Description" expanded="false">Description<ul>
<li><a href="et_desc.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="et_desc.html#id62437">Overview</a></li>
<li title="Filters and dictionary"><a href="et_desc.html#id63954">Filters and dictionary</a></li>
<li title="Trace clients"><a href="et_desc.html#id63394">Trace clients</a></li>
<li title="Global tracing"><a href="et_desc.html#id63541">Global tracing</a></li>
<li title="Viewer window"><a href="et_desc.html#id63682">Viewer window</a></li>
<li title="Configuration"><a href="et_desc.html#id65519">Configuration</a></li>
<li title="Contents viewer window"><a href="et_desc.html#id65550">Contents viewer window</a></li>
</ul>
</li>
<li id="no" title="Advanced examples" expanded="false">Advanced examples<ul>
<li><a href="et_examples.html">
              Top of chapter
            </a></li>
<li title="A simulated Mnesia transaction"><a href="et_examples.html#id65821">A simulated Mnesia transaction</a></li>
<li title="Some convenient functions used in the Mnesia transaction
    example"><a href="et_examples.html#id65930">Some convenient functions used in the Mnesia transaction
    example</a></li>
<li title="Erlang trace of a real Mnesia transaction"><a href="et_examples.html#id66086">Erlang trace of a real Mnesia transaction</a></li>
<li title="Erlang trace of Megaco startup"><a href="et_examples.html#id66211">Erlang trace of Megaco startup</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>2 Tutorial</h1>
  

  <h3><a name="id60778">2.1 
        Visualizing Message Sequence Charts</a></h3>
   
    
    <p>The easiest way of using <span class="code">ET</span>, is to just use it as a
    graphical tool for displaying message sequence charts. In order to
    do that you need to first start a <span class="code">Viewer</span> (which by default
    starts a <span class="code">Collector</span>):</p>

    <div class="example"><pre>
      {ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
      CollectorPid = et_viewer:get_collector_pid(ViewerPid).</pre></div>

    <a name="report_event"></a>
    <p>Then you send events to the <span class="code">Collector</span>
    with the function <span class="code">et_collector:report_event/6</span> like this:</p>
    
    <div class="example"><pre>
      et_collector:report_event(CollectorPid,85,from,to,message,extra_stuff).</pre></div>

    <p>The <span class="code">Viewer</span> will automatically pull events from the
    <span class="code">Collector</span> and display them on the screen.</p>

    <p>The number (in this case 85) is an integer from 1 to 100 that
    specifies the "detail level" of the message. The higher the
    number, the more important it is. This provides a crude form of
    priority filtering.</p>

    <p>The <span class="code">from</span>, <span class="code">to</span>, and <span class="code">message</span> parameters are
    exactly what they sound like. <span class="code">from</span> and <span class="code">to</span> are
    visualized in the <span class="code">Viewer</span> as "lifelines", with the message
    passing from one to the other. If <span class="code">from</span> and <span class="code">to</span> are
    the same value, then it is displayed next to the lifeline as an
    "action". The <span class="code">extra_stuff </span>value is simply data that you can
    attach that will be displayed when someone actually clicks on the
    action or message in the <span class="code">Viewer</span> window.</p>

    <p>The module <span class="code">et/examples/et_display_demo.erl</span> illustrates
    how it can be used:</p>
    
<div class="example"><pre>

-module(et_display_demo).

-export([test/0]).

test() -&gt;
    {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.</pre></div>    
    <p>When you run the <span class="code">et_display_demo:test().</span> function in the
    example above, the <span class="code">Viewer</span> window will look like this:</p>.
    
    <p></p>
    
    <img alt="IMAGE MISSING" src="coffee_order.png"><br>
      <em>Figure
        2.1:
         
        Screenshot of the <span class="code">Viewer</span> window</em>
    

 

  <h3><a name="id57439">2.2 
        Four Modules</a></h3>
    

    <p>The event tracer framework is made up of four modules:</p>

    <ul>
      <li><p><span class="code">et</span></p></li>
      <li><p><span class="code">et_collector</span></p></li>
      <li><p><span class="code">et_viewer</span></p></li>
      <li><p><span class="code">et_selector</span></p></li>
    </ul>

    <p>In addition, you'll probably want to familiarize yourself with
    the <span class="code">dbg</span> module and possibly <span class="code">seq_trace</span> module as
    well.</p>
  

  <h3><a name="id61823">2.3 
        The Event Tracer Interface</a></h3>
    

    <p>The <span class="code">et</span> module is not like other modules. It contains a
    function called <span class="code">et:trace_me/5</span>. Which is a function that
    does not do any useful stuff at all. Its sole purpose is to be a
    function that is easy to trace. A call to it may be something
    like:</p>

    <div class="example"><pre>
      et:trace_me(85,from,to,message,extra_stuff).</pre></div>

    <p>The parameters to <span class="code">et:trace_me/5</span> are the same as to
    <span class="bold_code"><a href="#report_event"><span class="code">et_collector:report_event/6</span></a></span>
    in the previous chapter. The big difference between the two is in
    the semantics of the two functions. The second actually reports an
    <span class="code">Event</span> to the <span class="code">Collector</span> while the first does nothing,
    it just returns the atom <span class="code">hopefully_traced</span>. In order to make
    the parameters to <span class="code">et:trace_me/5</span> turn up in the
    <span class="code">Collector</span>, tracing of that function must be activated and
    the <span class="code">Collector</span> must be registered as a <span class="code">Tracer</span> of the
    <span class="code">Raw Trace Data</span>.</p>

    <p>Erlang tracing is a seething pile of pain that involves
    reasonably complex knowledge of clever ports, tracing return
    formats, and specialized tracing <span class="code">MatchSpecs</span> (which are
    really their own special kind of hell). The tracing mechanism is
    very powerful indeed, but it can be hard to grasp.</p>

    <p>Luckily there is a simplified way to start tracing of
    <span class="code">et:trace_me/5</span> function calls. The idea is that you should
    instrument your code with calls to <span class="code">et:trace_me/5</span> in
    strategic places where you have interesting information available
    in your program. Then you just start the <span class="code">Collector</span> with
    global tracing enabled:</p>

    <div class="example"><pre>
      et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).</pre></div>

    <p>This will start a <span class="code">Collector</span>, a <span class="code">Viewer</span> and also
    start the tracing of <span class="code">et:trace_me/5</span> function calls. The
    <span class="code">Raw Trace Data</span> is collected by the <span class="code">Collector</span> and a
    view of it is displayed on the screen by the <span class="code">Viewer</span>. You
    can define your own "views" of the data by implementing your own
    <span class="code">Filter</span> functions and register them in the
    <span class="code">Viewer</span>.</p>
  

  <h3><a name="id56971">2.4 
        The Collector and Viewer</a></h3>
    

    <p>These two pieces work in concert. Basically, the
    <span class="code">Collector</span> receives <span class="code">Raw Trace Data</span> and processes it
    into <span class="code">Events</span> in a <span class="code">et</span> specific format (defined in
    <span class="code">et/include/et.hrl</span>). The <span class="code">Viewer</span> interrogates the
    <span class="code">Collector</span> and displays an interactive representation of the
    data.</p>

    <p>You might wonder why these aren't just one module. The
    <span class="code">Collector</span> is a generic full-fledged framework that allows
    processes to "subscribe" to the <span class="code">Events</span> that it
    collects. One <span class="code">Collector</span> can serve several
    <span class="code">Viewers</span>. The typical case is that you have one
    <span class="code">Viewer</span> that visualizes <span class="code">Events</span> in one flavor and
    another <span class="code">Viewer</span> that visualizes them in another flavor. If
    you for example are tracing a text based protocol like <span class="code">HTML</span>
    (or <span class="code">Megaco/H.248</span>) it would be useful to be able to display
    the <span class="code">Events</span> as plain text as well as the internal
    representation of the message. The architecture does also allow
    you to implement your own <span class="code">Viewer</span> program as long as it
    complies to the protocol between the <span class="code">Collector/Viewer</span>
    protocol. Currently two kinds of <span class="code">Viewers</span> exists. That is
    the old <span class="code">GS</span> based one and the new based on
    <span class="code">wxWidgets</span>. But if you feel for it you may implement your
    own <span class="code">Viewer</span>, which for example could display the
    <span class="code">Events</span> as ASCII art or whatever you feel useful.</p>

    <p>The <span class="code">Viewer</span> will by default create a <span class="code">Collector</span> for
    you. With a few options and some configuration settings you can
    start collecting <span class="code">Events</span>.</p>

    <p>The <span class="code">Collector</span> API does also allow you to save the
    collected <span class="code">Events</span> to file and later load them in a later
    session.</p>

  

  <h3><a name="id58113">2.5 
        The Selector</a></h3>
    

    <p>This is perhaps the most central module in the entirety of the
    <span class="code">et</span> suite. The <span class="code">Collector</span> needs "filters" to convert
    the <span class="code">Raw Trace Data</span> into "events" that it can display. The
    <span class="code">et_selector</span> module provides the default <span class="code">Filter</span> and
    some API calls to manage the <span class="code">Trace Pattern</span>. The
    <span class="code">Selector</span> provides various functions that achieve the
    following:</p>

    <ul>
      <li><p>Convert <span class="code">Raw Trace Data</span> into an appropriate
      <span class="code">Event</span></p></li>
      <li><p>Magically notice traces of the <span class="code">et:trace_me/5</span>
      function and make appropriate <span class="code">Events</span></p></li>
      <li><p>Carefully prevent translating the <span class="code">Raw Trace Data</span>
      twice</p></li>
      <li><p>Manage a <span class="code">Trace Pattern</span></p></li>
    </ul>

    <p>The <span class="code">Trace Pattern</span> is basically a tuple of a
    <span class="code">module</span> and a <span class="code">detail level</span> (either an integer or the
    atom max for full detail). In most cases the <span class="code">Trace Pattern</span>
    <span class="code">{et,max}</span> does suffice. But if you do not want any runtime
    dependency of <span class="code">et</span> you can implement your own
    <span class="code">trace_me/5</span> function in some module and refer to that module
    in the <span class="code">Trace Pattern</span>.</p>

    <p>The specified module flows from your instantiation of the
    <span class="code">Viewer</span>, to the <span class="code">Collector</span> that it automatically
    creates, gets stashed in as the <span class="code">Trace Pattern</span>, and
    eventually goes down into the bowels of the <span class="code">Selector</span>.</p>

    <p>The module that you specify gets passed down (eventually) into
    <span class="code">Selector</span>'s default <span class="code">Filter</span>. The format of the
    <span class="code">et:trace_me/5</span> function call is hardcoded in that
    <span class="code">Filter</span>.</p>

  

  <h3><a name="id62590">2.6 
        How To Put It Together</a></h3>
    

    <p>The <span class="code">Collector</span> automatically registers itself to listen
    for trace <span class="code">Events</span>, so all you have to do is enable them.</p>

    <p>For those people who want to do general tracing, consult the
    <span class="code">dbg</span> module on how to trace whatever you're interested in
    and let it work its magic. If you just want <span class="code">et:trace_me/5</span>
    to work, do the following:</p>

    <ul>
      <li><p>Create a <span class="code">Collector</span></p></li>
      <li><p>Create a <span class="code">Viewer</span> (this can do step #1 for you)</p></li>
      <li><p>Turn on and pare down debugging</p></li>
    </ul>

    <p>The module <span class="code">et/examples/et_trace_demo.erl</span> achieves this.</p>

<div class="example"><pre>

-module(et_trace_demo).

-export([test/0]).

test() -&gt;
    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.</pre></div>
    <p>Running through the above, the most important points are:</p>

    <ul>
      <li><p>Turn on global tracing</p></li>
      <li><p>Set a <span class="code">Trace Pattern</span></p></li>
      <li><p>Tell <span class="code">dbg</span> to trace function Calls</p></li>
      <li><p>Tell it specifically to trace the <span class="code">et:trace_me/5</span> function</p></li>
    </ul>

    <p>When you run the <span class="code">et_trace_demo:test()</span> function above, the
    <span class="code">Viewer</span> window will look like this screenshot:</p>.

    <p></p>
    
    <img alt="IMAGE MISSING" src="coffee_order.png"><br>
      <em>Figure
        2.2:
         
        Screenshot of the <span class="code">Viewer</span> window</em>
    
    
  
    
</div>
<div class="footer">
<hr>
<p>Copyright © 2002-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>