1. 程式人生 > >系統技術非業餘研究 » Erlang如何檢視gen_server系列的狀態 (高階)

系統技術非業餘研究 » Erlang如何檢視gen_server系列的狀態 (高階)

gen_server在erlang otp程式設計中的地位是無可撼動的,幾乎都是gen_server或者gen_fsm的模型。那麼程式執行起來的時候 我們如何檢視gen_server的內部狀態呢。有2種方法:
1. 自己寫個類似於info這樣的函式,來獲取狀態。
2. 利用系統現有的架構。sasl應用帶了一個si的東西 全名是status inspector, 這個東西就是設計來幫使用者解決這個問題的。

實驗開始:

[email protected]:~# cat abc.erl
-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() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

test()->
    gen_server:call(?SERVER, {test, "param1"}).

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

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

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

format_status(_Opt, [_PDict, #state{a=A,
                                    b = B
                                    }]) ->
   
    [{data, [{"a===", A},
             {"b===", B}]}].
[email protected]:~# erl -boot start_sasl
Erlang R13B03 (erts-5.7.4) [/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,<0.35.0>},
                       {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,<0.36.0>},
                       {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,<0.34.0>},
                       {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,<0.37.0>},
                       {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: 
[email protected]
Eshell V5.7.4 (abort with ^G) 1> si:start(). %必須手動啟動 =PROGRESS REPORT==== 29-Oct-2009::16:07:31 === supervisor: {local,sasl_sup} started: [{pid,<0.43.0>}, {name,si_server}, {mfa,{si_sasl_supp,start_link,[[]]}}, {restart_type,temporary}, {shutdown,brutal_kill}, {child_type,worker}] {ok,<0.43.0>} 2> 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: "<A.B.C>", {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> abc:start_link(). {ok,<0.46.0>} 4> abc:test(). got msg {test,"param1"} ok 5> sys:log(abc,true). %開啟gen_server的訊息log功能 ok 6> abc:test(). %這個請求訊息被記錄 got msg {test,"param1"} ok 7> si:pi(abc). %好戲開始 Status for generic server abc =============================================================================== Pid <0.46.0> Status running Parent <0.41.0> Logged events %這個是log到的訊息 {10, [{{out,ok,<0.41.0>,{state,hello,world}}, abc, {gen_server,print_event}}, {{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>},{test,"param1"}}}, abc, {gen_server,print_event}}]} %這個是format_status的結果 如果沒有format_status那麼匯出是 {a=hello, b=world} a=== hello b=== world ok 8> 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,[<0.41.0>]}, {dictionary,[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}]}, {trap_exit,false}, {error_handler,error_handler}, {priority,normal}, {group_leader,<0.25.0>}, {total_heap_size,233}, {heap_size,233}, {stack_size,9}, {reductions,117}, {garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]}, {suspending,[]}] ok 9> sys:get_status(abc). {status,<0.46.0>, {module,gen_server}, [[{'$ancestors',[<0.41.0>]},{'$initial_call',{abc,init,1}}], running,<0.41.0>, [{log,{10, [{{out,ok,<0.41.0>,{state,hello,world}}, abc, {gen_server,print_event}}, {{in,{'$gen_call',{<0.41.0>,#Ref<0.0.0.85>}, {test,"param1"}}}, abc, {gen_server,print_event}}]}}], [abc,{state,hello,world},abc,infinity]]}

結論:
這個是文件未公開的功能。上面演示瞭如何sys開啟log, 如何察看gen_server的狀態

Post Footer automatically generated by wp-posturl plugin for wordpress.

No related posts.

相關推薦

系統技術業餘研究 » Erlang如何檢視gen_server系列狀態 高階

gen_server在erlang otp程式設計中的地位是無可撼動的,幾乎都是gen_server或者gen_fsm的模型。那麼程式執行起來的時候 我們如何檢視gen_server的內部狀態呢。有2種方法: 1. 自己寫個類似於info這樣的函式,來獲取狀態。 2. 利用系統現有的架構。sas

系統技術業餘研究 » Erlang程式碼反編譯以及檢視彙編碼

Erlang的程式碼是先翻譯成abstract_code,再到目的碼的,如果有符號資訊很容易恢復原始碼,通常我們部署系統的時候需要把符號資訊去掉,reltool就可以幹這個事情! 我們演示下: $ cat server.erl -module(server). -compile(export

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co

系統技術業餘研究 » Erlang R16B03釋出,R17已發力

Erlang R16B03釋出了,通常03版本是bug fix版本,進入生產版本,官方的說明如下: OTP R16B03 is a service release with mostly a number of small corrections and user contributions. B

系統技術業餘研究 » Erlang R13B04 Installation

R13B04後erlang的原始碼編譯為了考慮移植性,就改變了編譯方式,以下是官方wiki上的安裝文件: 1. Cloning Here are the basic steps to build Erlang/OTP in the Git repository. Start by cloning:

系統技術業餘研究 » Erlang R15的記憶體delayed dealloc特性對訊息密集型程式的影響

在新的NUMA體系結構下,每個CPU都有自己的本地記憶體,如果要訪問其他CPU的記憶體,那算remote了,要走CPU之間的QPI通道,通常這樣速度會有40%的下降。 那麼對於多執行緒的程式來講,這個硬體的變化對軟體也有很大的影響。在多執行緒程式裡面,通常一個執行緒會為一個物件分配記憶體,然後把這

系統技術業餘研究 » Erlang R17新特性淺評

Erlang R17RC2 原始碼已經就緒, 參見 這裡 後續版本的釋出時間,官方的時間安排參見 這裡,摘抄如下: Preliminary dates for the upcoming release: Release: erts, emu,comp |Code stop

系統技術業餘研究 » Erlang R16支援帶顏色的控制檯

Erlang通過fix tty驅動的過濾,在R16版本支援帶顏色的控制檯,這個特性在我們做各種監控工具高亮非常有幫助,參見R16的Readme: Support ANSI in console Unix platforms will no longer filter control sequenc

系統技術業餘研究 » 如何檢視節點的可用控制代碼數目和已用控制代碼數

很多同學在使用erlang的過程中, 碰到了很奇怪的問題, 後來查明都是檔案控制代碼不夠用了, 因為系統預設的是每個程序1024. 所以我們有必要在程式執行的時候, 瞭解這些資訊, 以便診斷和預警. 下面的這個程式就演示了這個如何檢視節點的可用控制代碼數目和已用控制代碼數的功能. 首先確保你已經安

系統技術業餘研究 » erlang coredump問題

早上成立濤同學問道: : :)我們最近發生了幾次宕機。。節點無緣無故就沒有了。也沒有crash dump,也不知道任何線索。 我們知道erlang的VM在正常運作的時候,如果發現erlang程式的異常或者虛擬機器資源不夠如記憶體不夠的時候,會產生erl_crash.dump檔案,裡面把crash的

系統技術業餘研究 » Erlang open_port極度影響效能的因素

Erlang的port相當於系統的IO,打開了Erlang世界通往外界的通道,可以很方便的執行外部程式。 但是open_port的效能對整個系統來講非常的重要,我就帶領大家看看open_port影響效能的因素。 首先看下open_port的文件: {spawn, Command} Star

系統技術業餘研究 » Erlang節點重啟導致的incarnation問題

今天晚上mingchaoyan同學在線上問以下這個問題: 152489 =ERROR REPORT==== 2013-06-28 19:57:53 === 152490 Discarding message {send,<<19 bytes>>} from <0.8

系統技術業餘研究 » Erlang port巧用環境變數

Erlang與外面世界的互動主要通過port來進行的,特別是和外部程式的協作,通常是通過管道進行的。 基本上有2種方法可以呼叫外部程式: 1. os:cmd 2. erlang:open_port, 這二種方式各有利弊,先看文件: os:cmd的文件參見這裡 cmd(Command) ->

系統技術業餘研究 » Erlang新新增選項 +zerts_de_busy_limit 控制節點間通訊的資料量

erlang節點間通訊預設是通過tcp通道進行的, 而且每對節點間只有一個tcp連結,所有的rpc和內建的類似monitor這樣的訊息也都是通過這個通道進行的. 當資料量過大的時候, 系統就會發出 busy distribution port警告, 同時限制資料的吞吐. 這個值預設是128k. 現

系統技術業餘研究 » Erlang Shell實用小技巧

Erlang Shell下有很多內建的命令,在平時互動的時候很好用,文件裡面都是一行帶過,大家可能沒什麼感覺。 我來重點講解和演示下: $ erl Erlang R14B04 (erts-5.8.5) [/source] [smp:2:2] [rq:2] [async-threads:0] [h

系統技術業餘研究 » ”Erlang supervisor 極其白痴的 Bug“的澄清

2008-05-26的時候, 著名的Trustno1發表了這篇文章 http://www.iteye.com/topic/197097 抱怨Erlang supervisor 極其白痴的一個bug. 今天 @淘李福 同學重新提起這個事情: 翻到一個老帖子: http://www.iteye.com

系統技術業餘研究 » Erlang叢集RPC通道擁塞問題及解決方案

Erlang的叢集預設情況下是全聯通的,也就是當一個節點加入叢集的時候,介紹人會推薦叢集裡面所有的節點主動來和新加入的節點建立聯絡, 效果如下圖: 我們這次不講如何避免全聯通而是來講這個節點間通道的問題。 我們知道erlang的訊息傳送是透明的,只要呼叫Pid!Msg, 虛擬機器和叢集的基礎設

系統技術業餘研究 » Erlang match_spec引擎介紹和應用

match_spec是什麼呢? A “match specification” (match_spec) is an Erlang term describing a small “program” that will try to match something (either the para

系統技術業餘研究 » init_debug檢視系統boot過程

erl啟動的時候有個引數 -init_debug 作用是 Makes init write some debug information while interpreting the boot script. 參見erlang system_principles的1.3節:Boot Scripts

系統技術業餘研究 » Erlang虛擬機器基礎設施dtrace探測點介紹和使用

最新的Erlang虛擬機器(R15B01)很大的一個改進就是加入了對dtrace探測點的支援了, 具體參見這裡, 主要目標是方便在生產實踐中定位複雜的效能問題。 目前Erlang的虛擬機器的探測點支援Linux的systemtap和freebsd的dtrace,我們剛好能夠享受的到。 作者Scot