2009-12-23 33 views
62

我試圖開始使用erlang:trace/3和dbg模塊來跟蹤活動生產系統的行爲而不關閉服務器。在Erlang中使用跟蹤和dbg

documentationopaque(說得溫和),並且在網上似乎沒有任何有用的教程。

我整天試圖做的事情是通過嘗試將模板應用於模塊:函數,使用dbg:c和dbg:p捕獲特定函數中發生的事情,但根本沒有成功...

有沒有人有一個簡潔的解釋如何在現場Erlang系統中使用跟蹤?

回答

7

如果你更喜歡圖形示蹤,然後嘗試erlyberly。它允許您選擇想要跟蹤的功能(在當前的所有進程中)並處理dbg API。

但是它不能防止過載,所以不適合生產系統。

enter image description here

82

跟蹤函數調用的基本步驟是沒有生命力的節點上:

> dbg:start(). % start dbg 
> dbg:tracer(). % start a simple tracer process 
> dbg:tp(Module, Function, Arity, []). % specify MFA you are interested in 
> dbg:p(all, c). % trace calls (c) of that MFA for all processes. 

... trace here 

> dbg:stop_clear(). % stop tracer and clear effect of tp and p calls. 

您可以跟蹤的同時多種功能。通過爲每個功能調用tp來添加功能。如果要跟蹤非導出函數,則需要致電tpl。要刪除功能,請以類似的方式撥打ctpctpl。一些普通的tp電話是:

> dbg:tpl(Module, '_', []). % all calls in Module 
> dbg:tpl(Module, Function, '_', []). % all calls to Module:Function with any arity. 
> dbg:tpl(Module, Function, Arity, []). % all calls to Module:Function/Arity. 
> dbg:tpl(M, F, A, [{'_', [], [{return_trace}]}]). % same as before, but also show return value. 

最後一個參數是匹配規範。你可以使用dbg:fun2ms來玩。

您可以通過調用p()來選擇要跟蹤的進程。這些項目在erlang:trace下描述。有些電話是:

> dbg:p(all, c). % trace calls to selected functions by all functions 
> dbg:p(new, c). % trace calls by processes spawned from now on 
> dbg:p(Pid, c). % trace calls by given process 
> dbg:p(Pid, [c, m]). % trace calls and messages of a given process 

我想你永遠都不需要直接調用erlang:trace,爲dbg確實幾乎一切都是爲了你。

活動節點的黃金法則是隻生成一定量的跟蹤輸出到shell,它允許您鍵入dbg:stop_clear().。 :)

我經常使用一個示蹤劑,它會在一系列事件後自動停止。例如:

dbg:tracer(process, {fun (_,100) -> dbg:stop_clear(); 
         (Msg, N) -> io:format("~p~n", [Msg]), N+1 end, 0 
        }). 

如果您正在尋找在遠程節點(或多個節點)調試,搜索paneperinvisoonviso

+1

我一直沒能得到跟蹤送* *任何與殼至今:( – 2009-12-23 20:03:38

+0

你說的這些都是非活動節點上的基本步驟......因爲在想必活動節點,你只需要滾動到外殼(和丟失)? – 2009-12-23 20:14:13

+1

跟蹤需要系統中的一些資源,如果你跟蹤頻繁的事件,你可能會冒你的表現,在最糟糕的情況下,你將失去聯繫,並且它去-Boom-。 – Zed 2009-12-23 20:19:02

18

在我們很少追蹤到shell的實時系統上。 如果系統配置良好,那麼它已經在收集打印到shell的Erlang日誌。我不必強調這是爲什麼在任何活動節點的關鍵...

讓我解釋追查到文件:

它可以跟蹤到文件,這將產生一個二進制輸出,可稍後轉換並解析。 (用於進一步的分析或自動化控制系統等)

一個例子可以是:

  • 跟蹤到包裹多個文件(12x50兆字節)。在使用這麼大的跟蹤之前,請務必檢查可用的磁盤空間!

    dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})). 
    

    dbg:p(all,[call,timestamp,return_to]).

      進入什麼活節點的前殼測試節點上
    • 始終測試!
    • 建議首先有一個測試節點或副本節點來嘗試腳本。

那說,讓我們來看看一個基本的跟蹤命令序列:

< 1>dbg:stop_clear().

  • 始終沖洗跟蹤端口,並確保沒有啓動先前的跟蹤會干擾當前跟蹤。

< 2>dbg:tracer().

  • 啓動示蹤劑過程。

< 3>dbg:p(all,[call, timestamp]).

  • 在這種情況下,我們跟蹤的所有過程和函數調用。

< 4>dbg:tp(...).

  • 正如捷思銳的回答看出。

< 5>dbg:tpl(...).

  • 正如捷思銳的回答看出。

< 42>dbg:stop_clear().

  • 再次它是爲了確保所有痕跡被寫入到輸出和逃避任何以後的不便。

您可以:

  • 定義一些有趣的添加觸發器() - S的外殼在給定的時間或事件停止跟蹤。遞歸fun() - s是最好的實現,但在應用這些時要非常小心。

  • 應用十分廣泛的模式匹配,以確保您只追查與特定類型參數的特定函數調用的具體過程...

我有一個問題,而回,當我們必須檢查ETS表格的內容和某個條目的出現時,我們必須在2-3分鐘內停止追蹤。

我還建議由Francesco Cesarini編寫的Erlang編程。 (Erlang Programming @ Amazon

8

'dbg'模塊是相當低級的東西。我經常需要使用非常經常使用的兩種攻擊手段,即 。

  1. 使用Erlang CLI/shell擴展代碼http://www.snookles.com/erlang/user_default.erl。它最初是由Serge Aleynikov編寫的(據我所知)和 一直是一個有用的「所以這就是我如何添加自定義函數到shell」的例子。編譯 模塊並編輯〜/ .erlang文件以指向其路徑(請參閱文件頂部 的註釋)。

  2. 使用與EPER集合工具捆綁在一起的「redbug」實用程序。 使用'dbg'很容易在幾秒鐘內創建數百萬個跟蹤事件。在生產環境中做 可能是災難性的。對於開發或生產用途,redbug使幾乎不可能通過跟蹤引發的過載來殺死正在運行的系統。