inviso_chapter.sgml
来自「OTP是开放电信平台的简称」· SGML 代码 · 共 450 行 · 第 1/3 页
SGML
450 行
<!doctype chapter PUBLIC "-//Stork//DTD chapter//EN">
<!--
``The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved via the world wide web at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
The Initial Developer of the Original Code is Ericsson Utvecklings AB.
Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
AB. All Rights Reserved.''
$Id$
-->
<chapter>
<header>
<title>Inviso</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
</header>
<section>
<title>Introduction</title>
<p><em>inviso</em>: (Latin) to go to see, visit, inspect, look at.
</p>
<p>The Inviso trace system consists of one or several runtime components supposed to run on each Erlang node doing tracing and one control component which can run on any node with available processor power. Inviso may also be part of a higher layer trace tool. See the inviso-tool as an example. The implementation is spread out over the Runtime_tools and the Inviso Erlang/OTP applications. Erlang modules necessary to run the runtime component are located in Runtime_tools and therefore assumed to be available on any node. Even though Inviso is introduced with Erlang/OTP R11B the runtime component implementation is done with backward compatibility in mind. Meaning that it is possible to compile and run it on older Erlang/OTP releases.</p>
<image file="inviso_users_guide_pic1">
<icaption>Inviso Trace System Architecture Overview.</icaption>
</image>
<p>This document describes the control and runtime components of the Inviso trace system.</p>
<section>
<title>Underlying Mechanisms</title>
<p>Inviso is built on Erlang trace BIFs and standard linked in trace-port drivers for efficient trace message logging. This means that Inviso can not co-exist in runtime with any other trace tool using the trace BIFs.</p>
</section>
<section>
<title>Trace Recepie</title>
<p>This is a short step-by-step description of how tracing using Inviso can be done.</p>
<list type="ordered">
<item>Start the Inviso control component at any node. Preferably a node that is not participating in the "work" done by your "system". The control component runs independently and normally not linked to any other process. (Prompt 2 in the example below.)</item>
<item>Add all Erlang nodes to the inviso control component where you want to trace. This is starting runtime components on all involved Erlang nodes. Can include the node where the control component runs as well. Note that the Runtime_Tools application must be running on the nodes where runtime components shall be started. (Prompt 1 and 3 in the example below.)</item>
<item>Initiate tracing on the added nodes. Initiating tracing means "opening" the output to where trace-messages will be written. Most commonly this is a file. Note that it is not actually necessary to initiate the same tracing on all nodes. It might for instance be wise to use different filenames on different nodes. In the example below tracing is initiated on two nodes. The same node as where the shell is running (<c>node()</c>) and at <c>node2@hurin</c>. Further both "regular" tracing (<c>trace</c>) as well as trace information (<c>ti</c>) are specified for both nodes. (Prompt 4 in the example below).</item>
<item>If needing pid-to-alias translations, activate meta tracing on the necessary functions. This requires that trace information was specified when initiating tracing. (Prompt 5 in the example below illustrates using pid to locally registered name translations).</item>
<item>Set trace-patterns on the functions that shall be traced. (Prompt 6 in the example below).</item>
<item>Set process trace flags on necessary processes. Do not forget to use the <c>timestamp</c> flag in order to be able to merge log files together in chronological order. (Prompt 7 in the example below).</item>
<item>Run your code. (Prompt 8 in the example below).</item>
<item>Stop tracing (opposite of initiate tracing) and clear trace-patterns on the nodes. It is actually not necessary to stop tracing on all nodes at once. Nodes no longer of interest can be made to stop tracing before others. (Prompt 9 in the example below stops tracing. Prompt 13 removes all trace flags and trace patterns. Removing trace flags are really not necessary since those will be removed when the runtime components are stopped. Removing trace patterns may many times be necessary to "return" the node to a "clean" state from a trace perspective. Trace patterns are never automatically cleared by the runtime system unless the Erlang module in question is reloaded.)</item>
<item>If necessary fetch the log files from the various nodes. (Prompt 10 in the example blow).</item>
<item>Merge and format the log files. (Prompt 12 in the example below).</item>
<item>Stop the runtime components. This is important if the Erlang nodes are real "live" systems, and will not necessarily be stopped just because the tracing is completed. (Prompt 14 in the example below).</item>
</list>
<p>This "recepie" is valid also when tracing in a non-distributed environment. The only difference is that function calls not taking a node-name as argument are used. The runtime component will then of course run on the same node as the control component.</p>
<p>Simple example illustrating the above listed recipe. It traces on two nodes, node1 where the control component also runs. And node2 which is a remote node from the control components perspective. The example uses a mixture of API-calls specifying what nodes to trace on and API functions working on all added nodes. This is in this example interchangable since all to the control component known nodes are participating in the same way.</p>
<!-- 75 characters for preformatting
===========================================================================
-->
<pre>
Eshell V5.5 (abort with ^G)
(node1@hurin)1><input>application:start(runtime_tools).</input>
ok
(node1@hurin)2> <input>inviso:start().</input>
{ok,<0.56.0>}
(node1@hurin)3> <input>inviso:add_nodes([node(),node2@hurin],mytag).</input>
{ok,[{'node1@hurin',{ok,new}},
{'node2@hurin',{ok,new}}]}
(node1@hurin)4> <input>inviso:init_tracing(
[{node(),[{trace,{file,"tracefile_node1.log"}},{ti,{file,"trace_node1.ti"}}]},
{node2@hurin,[{trace,{file,"tracefile_node2.log"}},{ti,{file,"trace_node2.ti"}}]}]).</input>
{ok,[{'node1@hurin',{ok,[{trace_log,ok},{ti_log,ok}]}},
{'node2@hurin',{ok,[{trace_log,ok},{ti_log,ok}]}}]}
(node1@hurin)5> <input>inviso:tpm_localnames([node(),node2@hurin]).</input>
{ok,[{'node1@hurin',{{ok,1},{ok,1}}},
{'node2@hurin',{{ok,1},{ok,1}}}]}
(node1@hurin)6> <input>inviso:tpl([node(),node2@hurin],code,which,'_',[]).</input>
{ok,[{'node1@hurin',{ok,[2]}},
{'node2@hurin',{ok,[2]}}]}
(node1@hurin)7> <input>inviso:tf(all,[call,timestamp]).</input>
{ok,[{'node1@hurin',{ok,"/"}},
{'node2@hurin',{ok,"-"}}]}
(node1@hurin)8> <input>code:which(ordset).</input>
non_existing
(node1@hurin)9> <input>inviso:stop_tracing().</input>
{ok,[{'node1@hurin',{ok,idle}},
{'node2@hurin',{ok,idle}}]}
(node1@hurin)10> <input>inviso:fetch_log([node2@hurin],".","aprefix_").</input>
{ok,[{'node2@hurin',
{complete,[{trace_log,[{ok,"aprefix_tracefile_node2.log"}]},
{ti_log,[{ok,"aprefix_trace_node2.ti"}]}]}}]}
(node1@hurin)11> <input>inviso:list_logs([node()]).</input>
{ok,[{'node1@hurin',
{ok,[{trace_log,".",["tracefile_node1.log"]},
{ti_log,".",["trace_node1.ti"]}]}}]}
(node1@hurin)12> <input>inviso_lfm:merge(
[{node(),[{trace_log,["tracefile_node1.log"]},
{ti_log,["trace_node1.ti"]}]},
{node2@hurin,[{trace_log,["aprefix_tracefile_node2.log"]},
{ti_log,["aprefix_trace_node2.ti"]}]}],"theoutfile.txt").</input>
{ok,15}
(node1@hurin)13> <input>inviso:clear().</input>
{ok,[{'node1@hurin',{ok,{new,running}}},
{'node2@hurin',{ok,{new,running}}}]}
(node1@hurin)14> <input>inviso:stop_nodes().</input>
{ok,[{'node2@hurin',ok},
{'node1@hurin',ok}]}
(node1@hurin)15>
</pre>
</section>
</section>
<section>
<title>Incarnation runtime tags</title>
<p>Incarnation runtime tags are used to identify an incarnation of a runtime component. An incarnation is one "start-up" of a runtime component on a specific Erlang node. The reason why it can sometimes be necessary to examine the incarnation runtime tag is that a user wants to connect, adopt, an already running runtime component. This may be the case if the runtime component has autostarted or because the control component terminated without killing the runtime component. While the user has been out of control of the runtime component it may very well have terminated and been restarted. If it was restarted without the user's knowledge, its incarnation runtime tag has most likely changed. The user can therefore, if the current incarnation runtime tag is not what it is supposed to be, conclude that the runtime component is not "doing" what is expected.</p>
<p>The runtime tag is set at runtime component start-up. This is either done when it is started manually by a call to <c>inviso:add_nodes/X</c>, or according to a specification in one of the autostart configuration files.</p>
</section>
<section>
<title>Runtime component state and status</title>
<p>A runtime component has a state and a status. The possible states are: <c>new</c>, <c>tracing</c> and <c>idle</c>. A runtime component that is <c>tracing</c> has (possibly) open log files. A <c>new</c> runtime component has no current tracer-data. That is it lacks any history of what it has done just recently. An <c>idle</c> runtime component is no longer tracing. It does therefore have current tracer-data that describes what it did do when it was tracing.</p>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?