1
<?xml version="1.0" encoding="latin1" ?>
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
7
<year>2002</year><year>2010</year>
8
<holder>Ericsson AB. All Rights Reserved.</holder>
11
The contents of this file are subject to the Erlang Public License,
12
Version 1.1, (the "License"); you may not use this file except in
13
compliance with the License. You should have received a copy of the
14
Erlang Public License along with this software. If not, it can be
15
retrieved online at http://www.erlang.org/.
17
Software distributed under the License is distributed on an "AS IS"
18
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
19
the License for the specific language governing rights and limitations
24
<title>Advanced examples</title>
25
<prepared>Håkan Mattsson</prepared>
26
<responsible>Håkan Mattsson</responsible>
28
<approved>Håkan Mattsson</approved>
32
<file>et_examples.xml</file>
36
<title>A simulated Mnesia transaction</title>
37
<p>The Erlang code for running the simulated <c>Mnesia</c> transaction
38
example in the previous chapter is included in the
39
<c>et/examples/et_demo.erl</c> file:</p>
43
<codeinclude file="../../examples/et_demo.erl" tag="%sim_trans" type="erl"></codeinclude>
47
<codeinclude file="../../examples/et_demo.erl" tag="%mgr_actors" type="erl"></codeinclude>
49
<p>If you invoke the <c>et_demo:sim_trans()</c> function, a
50
<c>Viewer</c> window will pop up and the sequence trace will be
51
almost the same as if the following <c>Mnesia</c> transaction
52
would have been run:</p>
56
<code type="none"><![CDATA[
57
mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).]]></code>
59
<p>And the viewer window will look like:</p>
63
<code type="none"><![CDATA[
64
Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
65
[async-threads:0] [kernel-poll:false]
67
Eshell V5.7.4 (abort with ^G)
68
1> {ok, Viewer} = et_viewer:start([]).
70
2> et_demo:sim_trans().
71
{ok,{table_handle,<0.45.0>,24596,trace_ts,
72
#Fun<et_collector.0.62831470>}}]]></code>
76
<image file="sim_trans.png">
77
<icaption>A simulated <c>Mnesia</c> transaction which writes one
84
<title>Some convenient functions used in the <c>Mnesia</c> transaction
87
<p>The <c>module_as_actor</c> filter converts the <c>Event
88
Records</c> so the module names becomes actors and the invoked
89
functions becomes labels. If the information about who the caller
90
was it will be displayed as an arrow directed from the caller to
91
the callee. The <c>[{message, {caller}}, {return_trace}]</c>
92
options to <c>dbg:tpl/2</c> function will imply the necessary
93
information in the Erlang traces. Here follows the
94
<c>module_as_actor</c> filter:</p>
99
<codeinclude file="../../examples/et_demo.erl" tag="%module_as_actor" type="erl"></codeinclude>
101
<p>The <c>plain_process_info</c> filter does not alter the
102
<c>Event Records</c>. It merely ensures that the event not
103
related to processes are skipped:</p>
107
<codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info" type="erl"></codeinclude>
109
<p>The <c>plain_process_info_nolink</c> filter does not alter the
110
<c>Event Records</c>. It do makes use of the
111
<c>plain_process_info</c> , but do also ensure that the process
112
info related to linking and unlinking is skipped:</p>
116
<codeinclude file="../../examples/et_demo.erl" tag="%plain_process_info_nolink" type="erl"></codeinclude>
118
<p>In order to simplify the startup of an <c>et_viewer</c> process
119
with the filters mentioned above, plus some others (that also are
120
found in <c>et/examples/et_demo.erl</c> src/et_collector.erl the
121
<c>et_demo:start/0,1</c> functions can be used:</p>
125
<codeinclude file="../../examples/et_demo.erl" tag="%start" type="erl"></codeinclude>
127
<p>A simple one-liner starts the tool:</p>
129
<code type="none"><![CDATA[
130
erl -pa ../examples -s et_demo]]></code>
132
<p>The filters are included by the following parameters:</p>
136
<codeinclude file="../../examples/et_demo.erl" tag="%filters" type="erl"></codeinclude>
141
<title>Erlang trace of a real Mnesia transaction</title>
143
<p>The following piece of code <c>et_demo:trace_mnesia/0</c>
144
activates call tracing of both local and external function calls
145
for all modules in the <c>Mnesia</c> application. The call traces
146
are configured cover all processes (both existing and those that
147
are spawned in the future) and include timestamps for trace
148
data. It do also activate tracing of process related events for
149
<c>Mnesia</c>'s static processes plus the calling process (that is
150
your shell). Please, observe that the <c>whereis/1</c> call in the
151
following code requires that both the traced <c>Mnesia</c>
152
application and the <c>et_viewer</c> is running on the same
157
<codeinclude file="../../examples/et_demo.erl" tag="%trace_mnesia" type="erl"></codeinclude>
159
<p>The <c>et_demo:live_trans/0</c> function starts the global
160
<c>Collector</c>, starts a <c>Viewer</c>, starts <c>Mnesia</c>,
161
creates a local table, activates tracing (as described above) and
162
registers the shell process is as 'my_shell' for clarity. Finally
163
a simple <c>Mnesia</c> transaction that writes a single record
168
<codeinclude file="../../examples/et_demo.erl" tag="%live_trans" type="erl"></codeinclude>
170
<p>Now we run the <c>et_demo:live_trans/0</c> function:</p>
174
<code type="none"><![CDATA[
176
Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
177
[async-threads:0] [kernel-poll:false]
179
Eshell V5.7.4 (abort with ^G)
180
1> et_demo:live_trans().
181
{atomic,ok}]]></code>
183
<p>Please, explore the different filters in order to see how the traced
184
transaction can be seen from different point of views:</p>
188
<image file="live_trans.png">
189
<icaption>A real <c>Mnesia</c> transaction which writes one record</icaption>
195
<title>Erlang trace of Megaco startup</title>
197
<p>The <c>Event Tracer (ET)</c> tool was initially written in
198
order to demonstrate how messages where sent over the
199
<c>Megaco</c> protocol. This were back in the old days before the
200
standard bodies of <c>IETF</c> and <c>ITU</c> had approved
201
<c>Megaco</c> (also called <c>H.248</c>) as an international
204
<p>In the <c>Megaco</c> application of Erlang/OTP, the code is
205
carefully instrumented with calls to <c>et:trace_me/5</c>. For
206
each call a detail level is given in order to enable dynamic
207
control of the trace level in a simple manner.</p>
209
<p>The <c>megaco_filter</c> module implements a customized filter
210
for <c>Megaco</c> messages. It does also make use of
211
<c>trace_global</c> combined with usage of the
212
<c>trace_pattern</c>:</p>
216
<code type="none"><![CDATA[
217
-module(megaco_filter).
222
[{event_order, event_ts},
224
{max_actors, infinity},
225
{trace_pattern, {megaco, max}},
226
{trace_global, true},
227
{dict_insert, {filter, megaco_filter}, fun filter/1},
228
{active_filter, megaco_filter},
229
{title, "Megaco tracer - Erlang/OTP"}],
230
et_viewer:start(Options).]]></code>
232
<p>First we start an Erlang node with a global <c>Collector</c>
233
and its <c>Viewer</c>.</p>
237
<code type="none"><![CDATA[
239
Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
240
[async-threads:0] [kernel-poll:false]
242
Eshell V5.7.4 (abort with ^G)
243
(observer@falco)1> megaco_filter:start().
244
{ok,<0.48.0>}]]></code>
246
<p>Secondly we start another Erlang node which we connect the
247
observer node, before we start the application that we want to
248
trace. In this case we start a Media Gateway Controller that
249
listens for both TCP and UDP on the text and binary ports for
254
<code type="none"><![CDATA[
255
erl -sname mgc -pa ../../megaco/examples/simple
256
Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
257
[async-threads:0] [kernel-poll:false]
259
Eshell V5.7.4 (abort with ^G)
260
(mgc@falco)1> net:ping(observer@falco).
262
(mgc@falco)2> megaco:start().
264
(mgc@falco)3> megaco_simple_mgc:start().
266
{megaco_receive_handle,{deviceName,"controller"},
267
megaco_pretty_text_encoder,[],megaco_tcp,dynamic}},
269
{megaco_receive_handle,{deviceName,"controller"},
270
megaco_pretty_text_encoder,[],megaco_udp,dynamic}},
272
{megaco_receive_handle,{deviceName,"controller"},
273
megaco_binary_encoder,[],megaco_tcp,dynamic}},
275
{megaco_receive_handle,{deviceName,"controller"},
276
megaco_binary_encoder,[],megaco_udp,dynamic}}]}]]></code>
278
<p>And finally we start an Erlang node for the Media Gateways and
279
connect to the observer node. Each Media Gateway connects to the
280
controller and sends an initial Service Change message. The
281
controller accepts the gateways and sends a reply to each one
282
using the same transport mechanism and message encoding according
283
to the preference of each gateway. That is all combinations of
284
TCP/IP transport, UDP/IP transport, text encoding and ASN.1 BER
289
<code type="none"><![CDATA[
290
Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
291
[async-threads:0] [kernel-poll:false]
293
Eshell V5.7.4 (abort with ^G)
294
(mg@falco)1> net:ping(observer@falco).
296
(mg@falco)2> megaco_simple_mg:start().
297
[{{deviceName,"gateway_tt"},
298
{error,{start_user,megaco_not_started}}},
299
{{deviceName,"gateway_tb"},
300
{error,{start_user,megaco_not_started}}},
301
{{deviceName,"gateway_ut"},
302
{error,{start_user,megaco_not_started}}},
303
{{deviceName,"gateway_ub"},
304
{error,{start_user,megaco_not_started}}}]
305
(mg@falco)3> megaco:start().
307
(mg@falco)4> megaco_simple_mg:start().
308
[{{deviceName,"gateway_tt"},
310
{ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
311
[{serviceChangeReply,
312
{'ServiceChangeReply',
313
[{megaco_term_id,false,["root"]}],
314
{serviceChangeResParms,
315
{'ServiceChangeResParm',
316
{deviceName,"controller"},
317
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
318
asn1_NOVALUE}}}}]}]}}},
319
{{deviceName,"gateway_tb"},
321
{ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
322
[{serviceChangeReply,
323
{'ServiceChangeReply',
324
[{megaco_term_id,false,["root"]}],
325
{serviceChangeResParms,
326
{'ServiceChangeResParm',
327
{deviceName,"controller"},
328
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
329
asn1_NOVALUE}}}}]}]}}},
330
{{deviceName,"gateway_ut"},
332
{ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
333
[{serviceChangeReply,
334
{'ServiceChangeReply',
335
[{megaco_term_id,false,["root"]}],
336
{serviceChangeResParms,
337
{'ServiceChangeResParm',
338
{deviceName,"controller"},
339
asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
340
asn1_NOVALUE}}}}]}]}}},
341
{{deviceName,"gateway_ub"},
343
{ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
344
[{serviceChangeReply,
345
{'ServiceChangeReply',
346
[{megaco_term_id,false,["root"]}],
347
{serviceChangeResParms,
348
{'ServiceChangeResParm',
349
{deviceName,"controller"},
350
asn1_NOVALUE,asn1_NOVALUE,
351
asn1_NOVALUE,...}}}}]}]}}}]]]></code>
353
<p>The <c>Megaco</c> adopted viewer looks like this, when we have clicked
354
on the <b>[gateway_tt]</b> actor name in order to only display the events
355
regarding that actor:</p>
359
<image file="megaco_tracer.png">
360
<icaption>The viewer adopted for Megaco</icaption>
363
<p>A pretty printed <c>Megaco</c> message looks like this:</p>
367
<image file="megaco_filter.png">
368
<icaption>A textual <c>Megaco</c> message</icaption>
371
<p>And the corresponding internal form for the same <c>Megaco</c> message
376
<image file="megaco_collector.png">
377
<icaption>The internal form of a <c>Megaco</c> message</icaption>