<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Erlang非业余研究 &#187; si</title>
	<atom:link href="http://blog.yufeng.info/archives/tag/si/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yufeng.info</link>
	<description>Erlang系统深度探索和应用</description>
	<lastBuildDate>Tue, 17 Jan 2012 06:05:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Erlang如何查看gen_server系列的状态 （高级）</title>
		<link>http://blog.yufeng.info/archives/99</link>
		<comments>http://blog.yufeng.info/archives/99#comments</comments>
		<pubDate>Thu, 29 Oct 2009 08:19:14 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Erlang探索]]></category>
		<category><![CDATA[gen_server]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[sasl]]></category>
		<category><![CDATA[si]]></category>
		<category><![CDATA[sys]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=99</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: Erlang如何查看gen_server系列的状态 （高级） gen_server在erlang otp编程中的地位是无可撼动的，几乎都是gen_server或者gen_fsm的模型。那么程序运行起来的时候 我们如何查看gen_server的内部状态呢。有2种方法： 1. 自己写个类似于info这样的函数，来获取状态。 2. 利用系统现有的架构。sasl应用带了一个si的东西 全名是status inspector, 这个东西就是设计来帮用户解决这个问题的。 实验开始: 结论： 这个是文档未公开的功能。上面演示了如何sys打开log, 如何察看gen_server的状态 Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/99">Erlang如何查看gen_server系列的状态 （高级）</a></p>
</div>
<p> gen_server在erlang otp编程中的地位是无可撼动的，几乎都是gen_server或者gen_fsm的模型。那么程序运行起来的时候 我们如何查看gen_server的内部状态呢。有2种方法：<br />
1. 自己写个类似于info这样的函数，来获取状态。<br />
2. 利用系统现有的架构。sasl应用带了一个si的东西 全名是status inspector, 这个东西就是设计来帮用户解决这个问题的。</p>
<p>实验开始:</p>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:~# cat abc.erl
</pre>
<pre class="brush: erlang; title: ; notranslate">
-module(abc).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-export([format_status/2]).
-export([test/0]).

-record(state, {a, b}).

-define(SERVER, ?MODULE).

start_link() -&gt;
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

test()-&gt;
    gen_server:call(?SERVER, {test, &quot;param1&quot;}).

init([]) -&gt;
    {ok, #state{a=hello, b=world}}.

handle_call({test, _} = Request, _From, State) -&gt;
    io:format(&quot;got msg ~p~n&quot;, [Request]),
    {reply, ok, State};

handle_call(_Request, _From, State) -&gt;
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) -&gt;
    {noreply, State}.

handle_info(_Info, State) -&gt;
    {noreply, State}.

terminate(_Reason, _State) -&gt;
    ok.

code_change(_OldVsn, State, _Extra) -&gt;
    {ok, State}.

format_status(_Opt, [_PDict, #state{a=A,
                                    b = B
                                    }]) -&gt;

    [{data, [{&quot;a===&quot;, A},
             {&quot;b===&quot;, B}]}].
</pre>
<pre class="brush: bash; title: ; notranslate">
root@nd-desktop:~# erl -boot start_sasl
Erlang R13B03 (erts-5.7.4) 1[/source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,&lt;0.35.0&gt;},
                       {name,alarm_handler},
                       {mfa,{alarm_handler,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]

=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,&lt;0.36.0&gt;},
                       {name,overload},
                       {mfa,{overload,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]

=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
          supervisor: {local,sasl_sup}
             started: [{pid,&lt;0.34.0&gt;},
                       {name,sasl_safe_sup},
                       {mfa,
                           {supervisor,start_link,
                               [{local,sasl_safe_sup},sasl,safe]}},
                       {restart_type,permanent},
                       {shutdown,infinity},
                       {child_type,supervisor}]

=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
          supervisor: {local,sasl_sup}
             started: [{pid,&lt;0.37.0&gt;},
                       {name,release_handler},
                       {mfa,{release_handler,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]

=PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
         application: sasl
          started_at: nonode@nohost
Eshell V5.7.4  (abort with ^G)
1&gt; si:start(). %必须手动启动

=PROGRESS REPORT==== 29-Oct-2009::16:07:31 ===
          supervisor: {local,sasl_sup}
             started: [{pid,&lt;0.43.0&gt;},
                       {name,si_server},
                       {mfa,{si_sasl_supp,start_link,[[]]}},
                       {restart_type,temporary},
                       {shutdown,brutal_kill},
                       {child_type,worker}]
{ok,&lt;0.43.0&gt;}
2&gt; si:help().

Status Inspection tool - usage
==============================
    For all these functions, Opt is an optional argument
    which can be 'normal' or 'all'; default is 'normal'.
    If 'all', all information will be printed.
    A Pid can be: &quot;&lt;A.B.C&gt;&quot;, {A, B, C}, B, a registered_name or an abbrev.
ANY PROCESS
si:pi([Opt,] Pid)   - Formatted information about any process that
                      SI recognises.
si:pi([Opt,] A,B,C) - Same as si:pi({A, B, C}).
si:ppi(Pid)         - Pretty formating of process_info.
                      Works for any process.
MISC
si:abbrevs()        - Lists valid abbreviations.
si:start_log(Filename) - Logging to file.
si:stop_log()
si:start()          - Starts Status Inspection (the si_server).
si:start([{start_log, FileName}])
si:stop()           - Shut down SI.
ok
3&gt; abc:start_link().
{ok,&lt;0.46.0&gt;}
4&gt; abc:test().
got msg {test,&quot;param1&quot;}
ok
5&gt; sys:log(abc,true). %打开gen_server的消息log功能
ok
6&gt; abc:test().  %这个请求消息被记录
got msg {test,&quot;param1&quot;}
ok
7&gt; si:pi(abc). %好戏开始

Status for generic server abc
===============================================================================
Pid                                                                    &lt;0.46.0&gt;
Status                                                                  running
Parent                                                                 &lt;0.41.0&gt;
Logged events  %这个是log到的消息
         {10,
         [{{out,ok,&lt;0.41.0&gt;,{state,hello,world}},
           abc,
           {gen_server,print_event}},
          {{in,{'$gen_call',{&lt;0.41.0&gt;,#Ref&lt;0.0.0.85&gt;},{test,&quot;param1&quot;}}},
           abc,
           {gen_server,print_event}}]}

%这个是format_status的结果  如果没有format_status那么导出是 {a=hello, b=world}

a===                                                                      hello
b===                                                                      world

ok
8&gt; si:ppi(abc).

Pretty Process Info
-------------------
[{registered_name,abc},
{current_function,{gen_server,loop,6}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[&lt;0.41.0&gt;]},
{dictionary,[{'$ancestors',[&lt;0.41.0&gt;]},{'$initial_call',{abc,init,1}}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,&lt;0.25.0&gt;},
{total_heap_size,233},
{heap_size,233},
{stack_size,9},
{reductions,117},
{garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},
{suspending,[]}]
ok

9&gt; sys:get_status(abc).
{status,&lt;0.46.0&gt;,
        {module,gen_server},
        [[{'$ancestors',[&lt;0.41.0&gt;]},{'$initial_call',{abc,init,1}}],
         running,&lt;0.41.0&gt;,
         [{log,{10,
                [{{out,ok,&lt;0.41.0&gt;,{state,hello,world}},
                  abc,
                  {gen_server,print_event}},
                 {{in,{'$gen_call',{&lt;0.41.0&gt;,#Ref&lt;0.0.0.85&gt;},
                                   {test,&quot;param1&quot;}}},
                  abc,
                  {gen_server,print_event}}]}}],
         [abc,{state,hello,world},abc,infinity]]}
</pre>
<p>结论：<br />
这个是文档未公开的功能。上面演示了如何sys打开log, 如何察看gen_server的状态</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/99/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

