erlang性能分析及進程監控工具

Etop

相似top命令。查看erlang進程佔用cpu、內存較高的進程
html

參數:
node

  node        atom       erlang node
  port        integer    The used port
  accumulate  boolean    If true execution time is accumulated
  lines       integer    Number of displayed processes
  interval    integer    Display update interval in secs
  sort        runtime | reductions | memory | msg_q
  output      graphical | text
  tracing     on | off 
  setcookie   string    

使用舉例:
web

1. 找出cpu佔用最高的進程,圖形界面輸出,每10秒更新一次
cookie

> spawn(fun() -> etop:start([{interval,10}, {sort, runtime}]) end).
> etop:stop().

2. 找出內存佔用較高進程, 輸出進程的數量爲20。文本形式輸出app

> spawn(fun() -> etop:start([{output, text}, {lines, 20},  {sort, memory}]) end).
> etop:stop().

3. 查看遠程節點etop:函數

 > erl -name abc@192.168.17.102 -hidden -s etop -output text -sort memory -lines 20 -node 'test@192.168.17.102' -setcookie mycookie123

或者:工具

> erl -name abc@192.168.17.102 -hidden
> etop:start([{node,'test@192.168.17.102'}, {setcookie, "mycookie123"}, {output, text}, {lines, 20},  {sort, memory}])

rpc:call
oop

> erl -name abc@192.168.17.102 -setcookie mycookie123 
> rpc:call('test@192.168.17.102', etop, start, [[{output, text}, {lines, 20},  {sort, memory}]]).


eprof

若是咱們使用etop查到了cpu佔用時間較多的進程id。那麼可以使用eprof進行進一步的分析.
post

基本使用方法:性能

> eprof:start().
> eprof:profile([pid(x,x,x)]).
> eprof:stop_profiling().
> eprof:analyze().
> eprof:stop().

或:

> eprof:start_profiling([regNames], {gen, call, 4}).
> eprof:stop_profiling().
> eprof:analyze().
> eprof:stop().

regNames可以填寫進程的註冊名, {gen, call, 4}表示僅僅記錄gen:call/4這個函數


analyze結果演示樣例:

****** Process <0.60.0>    -- 100.00 % of profiled time *** 
FUNCTION                 CALLS      %  TIME  [uS / CALLS]
--------                 -----    ---  ----  [----------]
gen:call/4                   2   0.00     0  [      0.00]
gen:do_call/4                2   0.22     1  [      0.50]
gen_server:call/2            2   0.44     2  [      1.00]
dbutil:i_connect/1           2   0.66     3  [      1.50]
gen:call/3                   2   0.66     3  [      1.50]
resource_pool:get/1          2   0.66     3  [      1.50]
mvar:modify/2                2   0.66     3  [      1.50]
gen_server:decode_msg/8      4   0.88     4  [      1.00]
erlang:monitor/2             2   0.88     4  [      2.00]
erlang:demonitor/2           2   1.33     6  [      3.00]
gen_server:handle_msg/5      4   1.55     7  [      1.75]
myserver:handle_call/3       4   1.77     8  [      2.00]
gen_server:loop/6            4   1.99     9  [      2.25]
erlang:send/3                2   3.76    17  [      8.50]
gen_server:reply/2           4  84.51   382  [     95.50]


fprof

fprof相似eprof,但是會把具體信息存儲到文件裏,方便數據統計分析。

僅僅看某一函數的簡單調用方法:

1> fprof:apply(Module, fun, Args).
2> fprof:profile().
3> fprof:analyse().

實際上在運行的時候,fprof:apply/3先後會本身主動加入trace([start, ...]) trace(stop).


完整的寫法是:

> fprof:trace([start, {file, "./fprof.trace"}, {procs, PidSpec}]).  %% 或者可以trace多個Pid,[PidSpec]
> fprof:trace(stop).
> fprof:profile({file, "./fprof.trace"}).
> fprof:analyse([{dest, "fprof.analysis"},{sort,own}]).  %% 具體參數見: http://www.erlang.org/doc/man/fprof.html#analyse-2

結果演示樣例:

1> fprof:apply(lists, reverse, ["abcdef"]).
"fedcba"
2> fprof:profile().
Reading trace data...

End of trace!
ok
3> fprof:analyse().
Processing data...
Creating output...
%% Analysis results:
{  analysis_options,
 [{callers, true},
  {sort, acc},
  {totals, false},
  {details, true}]}.

%                                               CNT       ACC       OWN        
[{ totals,                                        3,    0.027,    0.027}].  %%% CNT是trace過程當中函數調用的總數,ACC是整個trace的時間,OWN爲函數運行時間


%                                               CNT       ACC       OWN        
[{ "<0.33.0>",                                    3,undefined,    0.027}].   %%

{[{undefined,                                     0,    0.027,    0.019}],     
 { {fprof,apply_start_stop,4},                    0,    0.027,    0.019},     %
 [{{lists,reverse,1},                             1,    0.008,    0.005},      
  {suspend,                                       1,    0.000,    0.000}]}.    

{[{{fprof,apply_start_stop,4},                    1,    0.008,    0.005}],     
 { {lists,reverse,1},                             1,    0.008,    0.005},     %
 [{{lists,reverse,2},                             1,    0.003,    0.003}]}.    

{[{{lists,reverse,1},                             1,    0.003,    0.003}],     
 { {lists,reverse,2},                             1,    0.003,    0.003},     %
 [ ]}.

{[ ],
 { undefined,                                     0,    0.000,    0.000},     %
 [{{fprof,apply_start_stop,4},                    0,    0.027,    0.019}]}.    

{[{{fprof,apply_start_stop,4},                    1,    0.000,    0.000}],     
 { suspend,                                       1,    0.000,    0.000},     %
 [ ]}.


Done!
ok

%是一種標記,每一個「段落」中,%表示被調用的函數主體,%以上爲調用它的函數,%下面爲它調用的函數。「段落」中的CNT列表示被調用次數。Acc表示包含%之上的函數在內所花費的時間,own表示不包含%之上的函數所用的時間。

suspend表示進程掛起。

也可以將fprof這類工具卸載想監控的代碼先後。


cprof

用於統計一個函數中的每個函數的調用次數。

相較於eprof和fprof。cprof對性能影響很是小。官方說大約10%

使用舉例(引自官網)

1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.
1
2> cprof:analyse(calendar).
{calendar,9,
          [{{calendar,df,2},1},
           {{calendar,dm,1},1},
           {{calendar,dy,1},1},
           {{calendar,last_day_of_the_month1,2},1},
           {{calendar,last_day_of_the_month,2},1},
           {{calendar,is_leap_year1,1},1},
           {{calendar,is_leap_year,1},1},
           {{calendar,day_of_the_week,3},1},
           {{calendar,date_to_gregorian_days,3},1}]}
3> cprof:stop().
3271

該演示樣例代表day_of_the_week這個函數需要調用9個函數完畢計算。

相同cprof可以嵌入代碼中。



Webtool

webtool:start().  %% 默認port8888, http://localhost:8888/


appmon:start(). %% 查看application樹


pman:start().  %%監控進程


tv:start().  %% ets & mnesia


toolbar:start().  %% 包括了上面幾個

相關文章
相關標籤/搜索