Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4997751
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Erlang

2013-06-12 18:44:38

gen_server在erlang otp编程中的地位是无可撼动的,几乎都是gen_server或者gen_fsm的模型。那么程序运行起来的时候 我们如何查看gen_server的内部状态呢。有2种方法:
1. 自己写个类似于info这样的函数,来获取状态。
2. 利用系统现有的架构。sasl应用带了一个si的东西 全名是status inspector, 这个东西就是设计来帮用户解决这个问题的。

实验开始:

  1. root@nd-desktop:~# cat abc.erl
  2. -module(abc).
  3. -behaviour(gen_server).
  4. -export([start_link/0]).
  5. -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
  6. terminate/2, code_change/3]).
  7. -export([format_status/2]).
  8. -export([test/0]).
  9. -record(state, {a, b}).
  10. -define(SERVER, ?MODULE).
  11. start_link() ->
  12. gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
  13. test()->
  14. gen_server:call(?SERVER, {test, "param1"}).
  15. init([]) ->
  16. {ok, #state{a=hello, b=world}}.
  17. handle_call({test, _} = Request, _From, State) ->
  18. io:format("got msg ~p~n", [Request]),
  19. {reply, ok, State};
  20. handle_call(_Request, _From, State) ->
  21. Reply = ok,
  22. {reply, Reply, State}.
  23. handle_cast(_Msg, State) ->
  24. {noreply, State}.
  25. handle_info(_Info, State) ->
  26. {noreply, State}.
  27. terminate(_Reason, _State) ->
  28. ok.
  29. code_change(_OldVsn, State, _Extra) ->
  30. {ok, State}.
  31. format_status(_Opt, [_PDict, #state{a=A,
  32. b = B
  33. }]) ->
  34. [{data, [{"a===", A},
  35. {"b===", B}]}].
  36. root@nd-desktop:~# erl -boot start_sasl
  37. Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
  38. =PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
  39. supervisor: {local,sasl_safe_sup}
  40. started: [{pid,<0.35.0>},
  41. {name,alarm_handler},
  42. {mfa,{alarm_handler,start_link,[]}},
  43. {restart_type,permanent},
  44. {shutdown,2000},
  45. {child_type,worker}]
  46. =PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
  47. supervisor: {local,sasl_safe_sup}
  48. started: [{pid,<0.36.0>},
  49. {name,overload},
  50. {mfa,{overload,start_link,[]}},
  51. {restart_type,permanent},
  52. {shutdown,2000},
  53. {child_type,worker}]
  54. =PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
  55. supervisor: {local,sasl_sup}
  56. started: [{pid,<0.34.0>},
  57. {name,sasl_safe_sup},
  58. {mfa,
  59. {supervisor,start_link,
  60. [{local,sasl_safe_sup},sasl,safe]}},
  61. {restart_type,permanent},
  62. {shutdown,infinity},
  63. {child_type,supervisor}]
  64. =PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
  65. supervisor: {local,sasl_sup}
  66. started: [{pid,<0.37.0>},
  67. {name,release_handler},
  68. {mfa,{release_handler,start_link,[]}},
  69. {restart_type,permanent},
  70. {shutdown,2000},
  71. {child_type,worker}]
  72. =PROGRESS REPORT==== 29-Oct-2009::16:07:24 ===
  73. application: sasl
  74. started_at: nonode@nohost
  75. Eshell V5.7.4 (abort with ^G)
  76. 1> si:start(). %必须手动启动
  77. =PROGRESS REPORT==== 29-Oct-2009::16:07:31 ===
  78. supervisor: {local,sasl_sup}
  79. started: [{pid,<0.43.0>},
  80. {name,si_server},
  81. {mfa,{si_sasl_supp,start_link,[[]]}},
  82. {restart_type,temporary},
  83. {shutdown,brutal_kill},
  84. {child_type,worker}]
  85. {ok,<0.43.0>}
  86. 2> si:help().
  87. Status Inspection tool - usage
  88. ==============================
  89. For all these functions, Opt is an optional argument
  90. which can be 'normal' or 'all'; default is 'normal'.
  91. If 'all', all information will be printed.
  92. A Pid can be: "", {A, B, C}, B, a registered_name or an abbrev.
  93. ANY PROCESS
  94. si:pi([Opt,] Pid) - Formatted information about any process that
  95. SI recognises.
  96. si:pi([Opt,] A,B,C) - Same as si:pi({A, B, C}).
  97. si:ppi(Pid) - Pretty formating of process_info.
  98. Works for any process.
  99. MISC
  100. si:abbrevs() - Lists valid abbreviations.
  101. si:start_log(Filename) - Logging to file.
  102. si:stop_log()
  103. si:start() - Starts Status Inspection (the si_server).
  104. si:start([{start_log, FileName}])
  105. si:stop() - Shut down SI.
  106. ok
  107. 3> abc:start_link().
  108. {ok,<0.46.0>}
  109. 4> abc:test().
  110. got msg {test,"param1"}
  111. ok
  112. 5> sys:log(abc,true). %打开gen_server的消息log功能
  113. ok
  114. 6> abc:test(). %这个请求消息被记录
  115. got msg {test,"param1"}
  116. ok
  117. 7> si:pi(abc). %好戏开始
  118. Status for generic server abc
  119. ===============================================================================
  120. Pid <0.46.0>
  121. Status running
  122. Parent <0.41.0>
  123. Logged events %这个是log到的消息
  124. {10,
  125. [{{out,ok,<0.41.0>,{state,hello,world}},
  126. abc,
  127. {gen_server,print_event}},
  128. {{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},{test,"param1"}}},
  129. abc,
  130. {gen_server,print_event}}]}
  131. %这个是format_status的结果 如果没有format_status那么导出是 {a=hello, b=world}
  132. a=== hello
  133. b=== world
  134. ok
  135. 8> si:ppi(abc).
  136. Pretty Process Info
  137. -------------------
  138. [{registered_name,abc},
  139. {current_function,{gen_server,loop,6}},
  140. {initial_call,{proc_lib,init_p,5}},
  141. {status,waiting},
  142. {message_queue_len,0},
  143. {messages,[]},
  144. {links,[<0.41.0>]},
  145. {dictionary,[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}]},
  146. {trap_exit,false},
  147. {error_handler,error_handler},
  148. {priority,normal},
  149. {group_leader,<0.25.0>},
  150. {total_heap_size,233},
  151. {heap_size,233},
  152. {stack_size,9},
  153. {reductions,117},
  154. {garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},
  155. {suspending,[]}]
  156. ok
  157. 9> sys:get_status(abc). %当然你也可以这么看
  158. {status,<0.46.0>,
  159. {module,gen_server},
  160. [[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}],
  161. running,<0.41.0>,
  162. [{log,{10,
  163. [{{out,ok,<0.41.0>,{state,hello,world}},
  164. abc,
  165. {gen_server,print_event}},
  166. {{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},
  167. {test,"param1"}}},
  168. abc,
  169. {gen_server,print_event}}]}}],
  170. [abc,{state,hello,world},abc,infinity]]}




结论:
这个是文档未公开的功能。上面演示了如何sys打开log, 如何察看gen_server的状态

from:http://mryufeng.iteye.com/blog/506609
阅读(1530) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~