檢視原始碼 ttb (觀察器 v2.17)
用於建構分散式系統追蹤工具的基礎。
追蹤工具建構器 ttb
是用於建構分散式系統追蹤工具的基礎。
當使用 ttb
時,請勿並行使用應用程式 Runtime_Tools 中的模組 dbg
。
摘要
函式
等同於 tpl/4
。
讀取指定的二進制追蹤日誌。只要未指定選項 disable_sort
,日誌會依時間戳記的順序處理。
列出指定設定檔中的所有條目。
所有對 ttb
的呼叫都會儲存在歷史記錄中。此函式會傳回歷史記錄的目前內容。可以使用 run_history/1
重新執行任何條目,或使用 write_config/2,3
儲存在設定檔中。
在指定的程序或埠上設定指定的追蹤旗標。旗標 timestamp
一律會開啟。
執行指定設定檔中的所有條目。請注意,最後一次追蹤的歷史記錄始終可在檔案 ttb_last_config
中取得。
從指定的設定檔中執行選取的條目。NumList
是一個整數列表,指出要執行的條目。
從歷史記錄清單中執行指定的條目。若要列出歷史記錄,請使用 list_history/0
。
符合規格可以開啟或關閉循序追蹤。此函式會傳回一個符合規格,該規格會使用指定的 Flags
開啟循序追蹤。
此函式是一個快捷方式,允許使用一個命令啟動追蹤。Patterns
中的每個元組都會轉換為列表,然後將該列表傳遞至 ttb:tpl/2,3,4
。
停止所有節點上的追蹤。日誌和追蹤資訊檔案會傳送至追蹤控制節點,並儲存在名為 ttb_upload_FileName-Timestamp
的目錄中,其中 Filename
是在追蹤設定期間使用 {file, File}
提供,而 Timestamp
的格式為 yyyymmdd-hhmmss
。即使來自與追蹤控制節點位於同一台機器上的節點的日誌也會移至此目錄。歷史記錄清單會儲存到名為 ttb_last_config
的檔案中,以供進一步參考(因為無法再透過歷史記錄和組態管理函式存取,例如 ttb:list_history/0
)。
等同於 tpl/4
。
等同於 tpl/4
。
等同於 tpl/4
。
這些函式與追蹤旗標 call
、send
和 'receive'
一起使用,以設定和清除追蹤模式。
等同於 tracer(node())
。
常用追蹤設定的方便快捷方式。
在所有指定節點上啟動檔案追蹤埠,並將循序追蹤的系統追蹤器指向同一個埠。
建立或擴充設定檔,該設定檔可用於稍後還原特定組態。
檔案 .ti
包含 {Key,ValueList}
元組。此函式會將 Data
新增至與 Key
相關聯的 ValueList
。使用此函式寫入的所有資訊都包含在對格式處理器的呼叫中。
類型
-type format_handler() :: {format_fun(), InitialState :: term()}.
-type format_opt() :: {out, standard_io | file:filename()} | {handler, format_handler()} | disable_sort.
-type format_opts() :: format_opt() | [format_opt()].
-type match_spec() :: pos_integer() | x | c | cx | [] | dbg:match_spec().
-type stop_opt() :: nofetch | {fetch_dir, file:filename()} | format | {format, format_opts()} | return_fetch_dir.
-type tp_arity() :: arity() | '_'.
-type tp_function() :: atom() | '_'.
-type tp_module() :: module() | '_'.
-type trace_flag() :: s | r | m | c | p | sos | sol | sofs | all | clear | send | 'receive' | procs | ports | call | arity | return_to | silent | running | exiting | running_procs | running_ports | garbage_collection | timestamp | cpu_timestamp | monotonic_timestamp | strict_monotonic_timestamp | set_on_spawn | set_on_first_spawn | set_on_link | set_on_first_link | {tracer, pid() | port()} | {tracer, module(), term()}.
函式
-spec ctp() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctp(Module | {Module, Function, Arity}) -> {ok, MatchDesc :: match_desc()} | {error, term()} when Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity().
等同於 tpl/4
。
-spec ctp(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctp(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpe(Event) -> {ok, MatchDesc} | {error, term()} when Event :: send | 'receive', MatchDesc :: [MatchNum], MatchNum :: {matched, node(), 1} | {matched, node(), 0, RPCError :: term()}.
等同於 tpl/4
。
-spec ctpg() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpg(Module | {Module, Function :: tp_function(), Arity :: tp_arity()}) -> {ok, MatchDesc :: term()} | {error, term()} when Module :: tp_module().
等同於 tpl/4
。
-spec ctpg(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpg(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpl() -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpl(Module | {Module, Function :: tp_function(), Arity :: tp_arity()}) -> {ok, MatchDesc :: term()} | {error, term()} when Module :: tp_module().
等同於 tpl/4
。
-spec ctpl(Module :: tp_module(), Function :: tp_function()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec ctpl(Module :: tp_module(), Function :: tp_function(), Arity :: tp_arity()) -> {ok, MatchDesc :: match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec format(Files) -> ok | {error, term()} when Files :: [file:filename()] | file:filename().
等同於 format(Files, [])
。
-spec format(Files, Options) -> ok | {error, term()} when Files :: [file:filename()] | file:filename(), Options :: format_opts().
讀取指定的二進制追蹤日誌。只要未指定選項 disable_sort
,日誌會依時間戳記的順序處理。
如果 FormatHandler = {Function,InitialState}
,則會針對每個追蹤訊息呼叫 Function
。
如果 FormatHandler = get_et_handler()
,則會使用應用程式 ET 中的 et_viewer
來以圖形方式呈現追蹤日誌。ttb
提供一些不同的篩選器,可以從 et_viewer
中的「篩選器和縮放」選單中選取。
如果未指定 FormatHandler
,則會使用預設處理器,將每個追蹤訊息呈現為文字行。
從每次呼叫 Function
傳回的狀態會傳遞至下一次呼叫,即使下一次呼叫是要格式化來自另一個日誌檔案的訊息也一樣。
如果指定 Out
,則 FormatHandler
會取得 Out
的檔案描述元作為第一個參數。
如果使用 et
格式處理器,則會忽略 Out
。
包裝日誌可以一個接一個地格式化,也可以一次全部格式化。若要格式化一組包裝日誌中的一個日誌,請指定確切的檔案名稱。若要格式化整組包裝日誌,請指定名稱時以 *
取代包裝計數。如需範例,請參閱 使用者指南
。
-spec get_et_handler() -> {Fun, InitState} when Fun :: fun(), InitState :: term().
傳回 et
處理器,可用於 format/2
或 tracer/2
。
範例:ttb:format(Dir, [{handler, ttb:get_et_handler()}])
。
-spec list_config(ConfigFile) -> Result when ConfigFile :: file:filename(), Result :: Config | {error, term()}, Config :: [{integer(), mfas()}].
列出指定設定檔中的所有條目。
-spec list_history() -> History | {error, term()} when History :: [{N :: integer(), Func :: function(), Args :: integer()}].
所有對 ttb
的呼叫都會儲存在歷史記錄中。此函式會傳回歷史記錄的目前內容。可以使用 run_history/1
重新執行任何條目,或使用 write_config/2,3
儲存在設定檔中。
-spec p(Item, Flags) -> Result when Item :: item(), Flags :: trace_flag() | [trace_flag()], Result :: {ok, [{item(), match_desc()}]}.
在指定的程序或埠上設定指定的追蹤旗標。旗標 timestamp
一律會開啟。
有關可能的追蹤旗標,請參閱模組 dbg
的參考手冊。參數 MatchDesc
與從 dbg:p/2
傳回的參數相同。
程序可以指定為已註冊的名稱、全域已註冊的名稱或程序識別碼。埠可以指定為已註冊的名稱或埠識別碼。如果指定已註冊的名稱,則會在所有作用中的節點上,對具有此名稱的程序/埠設定旗標。
如果使用 tracer/2
指定選項 timer
,則發出此命令會啟動此追蹤的計時器。
-spec run_config(ConfigFile) -> Result when ConfigFile :: file:filename(), Result :: ok | {error, term()}.
執行指定設定檔中的所有條目。請注意,最後一次追蹤的歷史記錄始終可在檔案 ttb_last_config
中取得。
-spec run_config(ConfigFile, NumList) -> Result when ConfigFile :: file:filename(), NumList :: [integer()], Result :: ok | {error, term()}.
從指定的設定檔中執行選取的條目。NumList
是一個整數列表,指出要執行的條目。
若要列出設定檔的內容,請使用 list_config/1
。
請注意,最後一次追蹤的歷史記錄始終可在檔案 ttb_last_config
中取得。
-spec run_history(Entries) -> ok | {error, term()} when Entries :: [Entry] | Entry | all | all_silent, Entry :: integer().
從歷史記錄清單中執行指定的條目。若要列出歷史記錄,請使用 list_history/0
。
-spec seq_trigger_ms() -> match_spec().
等同於 seq_trigger_ms(all)
。
-spec seq_trigger_ms(Flags) -> match_spec() when Flags :: all | SeqTraceFlag | [SeqTraceFlag], SeqTraceFlag :: atom().
符合規格可以開啟或關閉循序追蹤。此函式會傳回一個符合規格,該規格會使用指定的 Flags
開啟循序追蹤。
此比對規格可以指定為 tp
或 tpl
的最後一個引數。啟用的 Item
隨即成為循序追蹤的觸發器。這表示如果項目在設定追蹤旗標 call
的程序上呼叫,則該程序會被「污染」上符記 seq_trace
。
如果 Flags = all
,則會設定所有可能的旗標。
SeqTraceFlag
的可能值可在 seq_trace
中找到。
關於 match_spec()
語法的描述,請參閱 ERTS 中的 Erlang 中的比對規格
一節,其中說明了一般的比對規格「語言」。
注意
當追蹤埠使用
ttb:tracer/0,1,2
啟動時,用於循序追蹤的系統追蹤器會由ttb
自動啟動。
以下是如何使用函式 seq_trigger_ms/0,1
的範例
(tiger@durin)5> ttb:tracer().
{ok,[tiger@durin]}
(tiger@durin)6> ttb:p(all,call).
{ok,{[all],[call]}}
(tiger@durin)7> ttb:tp(mod,func,ttb:seq_trigger_ms()).
{ok,[{matched,1},{saved,1}]}
(tiger@durin)8>
在此之後,每當呼叫 mod:func(...)
時,執行程序上都會設定符記 seq_trace
。
-spec start_trace(Nodes, Patterns, FlagSpec, TracerOpts) -> Result when Nodes :: nodes(), Patterns :: [tuple()], FlagSpec :: {item(), trace_flag() | [trace_flag()]}, TracerOpts :: term(), Result :: {ok, [{item(), match_desc()}]}.
此函式是一個快捷方式,允許使用一個命令啟動追蹤。Patterns
中的每個元組都會轉換為列表,然後將該列表傳遞至 ttb:tpl/2,3,4
。
呼叫
> ttb:start_trace([Node, OtherNode],
[{mod, foo, []}, {mod, bar, 2}],
{all, call},
[{file, File}, {handler,{fun myhandler/4, S}}]).
等同於
> ttb:start_trace([Node, OtherNode],
[{file, File}, {handler,{fun myhandler/4, S}}]),
ttb:tpl(mod, foo, []),
ttb:tpl(mod, bar, 2, []),
ttb:p(all, call).
-spec stop() -> stopped | {stopped, Dir :: file:filename()}.
等同於 stop([])
。
-spec stop(Opts :: stop_opts()) -> stopped | {stopped, Dir :: file:filename()}.
停止所有節點上的追蹤。日誌和追蹤資訊檔案會傳送至追蹤控制節點,並儲存在名為 ttb_upload_FileName-Timestamp
的目錄中,其中 Filename
是在追蹤設定期間使用 {file, File}
提供,而 Timestamp
的格式為 yyyymmdd-hhmmss
。即使來自與追蹤控制節點位於同一台機器上的節點的日誌也會移至此目錄。歷史記錄清單會儲存到名為 ttb_last_config
的檔案中,以供進一步參考(因為無法再透過歷史記錄和組態管理函式存取,例如 ttb:list_history/0
)。
選項
nofetch
- 表示追蹤停止後,不應收集追蹤記錄。{fetch, Dir}
- 允許指定要提取資料的目錄。如果目錄已存在,則會拋出錯誤。format
- 表示追蹤停止後要格式化追蹤記錄。提取目錄中的所有記錄都會合併。return_fetch_dir
- 表示傳回值為{stopped, Dir}
,而不僅僅是stopped
。這表示fetch
。
-spec tp(tp_module(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec tp(tp_module(), tp_function(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec tp(tp_module(), tp_function(), tp_arity(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec tpe(Event, MatchSpec) -> {ok, MatchDesc :: match_desc()} | {error, term()} when Event :: send | 'receive', MatchSpec :: match_spec().
等同於 tpl/4
。
-spec tpl(tp_module(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec tpl(tp_module(), tp_function(), match_spec()) -> {ok, match_desc()} | {error, term()}.
等同於 tpl/4
。
-spec tpl(tp_module(), tp_function(), tp_arity(), match_spec()) -> {ok, match_desc()} | {error, term()}.
這些函式與追蹤旗標 call
、send
和 'receive'
一起使用,以設定和清除追蹤模式。
當程序上設定追蹤旗標 call
時,如果為呼叫的函式設定了追蹤模式,則會在該程序上追蹤函式呼叫。
send
和 'receive'
旗標啟用追蹤程序/埠所傳送和接收的所有訊息。使用 tpe
設定的追蹤模式可以根據訊息內容、傳送者和/或接收者來限制追蹤的訊息。
追蹤模式使用比對規格來指定如何追蹤函式或訊息。比對規格在 ERTS 使用者指南
中進行說明。
這些函式等同於模組 dbg
中的對應函式,但所有呼叫都儲存在歷程記錄中。歷程記錄緩衝區讓建立組態檔變得容易;相同的追蹤環境可以設定多次,例如,比較兩次測試執行。當從 Erlang Shell 中使用 ttb
時,也可以減少輸入量。
tp
- 設定全域函式呼叫的追蹤模式。tpl
- 設定本機和全域函式呼叫的追蹤模式。tpe
- 設定訊息的追蹤模式。ctp
- 清除本機和全域函式呼叫的追蹤模式。ctpl
- 清除本機函式呼叫的追蹤模式。ctpg
- 清除全域函式呼叫的追蹤模式。ctpe
- 清除訊息的追蹤模式。
使用 tp
和 tpl
,可以使用其中一個比對規格捷徑(例如,ttb:tp(foo_module, caller)
)。
捷徑如下
return
- 對於[{'_',[],[{return_trace}]}]
(報告追蹤函式的傳回值)caller
- 對於[{'_',[],[{message,{caller}}]}]
(報告呼叫函式){codestr, Str}
- 對於以字串形式傳遞的dbg:fun2ms/1
引數(例如:"fun(_) -> return_trace() end"
)
等同於 tracer(node())
。
常用追蹤設定的方便快捷方式。
shell
等同於 tracer(node(),[{file, {local, "ttb"}}, shell])
。
dbg
等同於 tracer(node(),[{shell, only}])
。
Nodes
等同於 tracer(Nodes,[])
。
-spec tracer(Nodes, Opts) -> Result when Nodes :: nodes(), Opts :: Opt | [Opt], Opt :: {file, Client} | {handler, format_handler()} | {process_info, boolean()} | shell | {shell, ShellSpec} | {timer, TimerSpec} | {overload_check, {MSec, Module, Function}} | {flush, MSec} | resume | {resume, MSec} | {queue_size, non_neg_integer()}, TimerSpec :: MSec | {MSec, stop_opts()}, MSec :: integer(), Module :: atom(), Function :: atom(), Client :: File | {local, File}, File :: file:filename() | Wrap, Wrap :: {wrap, file:filename()} | {wrap, file:filename(), Size :: integer(), Count :: integer()}, ShellSpec :: true | false | only, Result :: {ok, [node()]} | {error, term()}.
在所有指定節點上啟動檔案追蹤埠,並將循序追蹤的系統追蹤器指向同一個埠。
選項
Filename
- 指定的Filename
會以節點名稱作為前綴。預設Filename
為ttb
。File={wrap,Filename,Size,Count}
- 如果必須限制追蹤記錄的大小,則可以使用。預設值為Size=128*1024
和Count=8
。Client
- 追蹤無碟節點時,必須從具有磁碟存取的外部「追蹤控制節點」啟動ttb
,且Client
必須為{local, File}
。然後,所有追蹤資訊都會傳送至追蹤控制節點,並在該節點上寫入檔案。queue_size
- 當追蹤至 shell 或{local,File}
時,內部會使用 IP 追蹤驅動程式。IP 追蹤驅動程式具有最多QueueSize
訊息的佇列,正在等待傳遞。如果驅動程式無法像產生訊息一樣快速地傳遞訊息,則可能會超過佇列大小,並丟棄訊息。此參數是可選的,且僅在追蹤處理常式接收到許多{drop,N}
追蹤訊息時才有用。如果未使用 shell 或{local,File}
,則沒有意義。有關 IP 追蹤驅動程式的詳細資訊,請參閱dbg:trace_port/2
。process_info
- 表示是否要收集程序資訊。如果PI = true
(預設值),則每個程序識別碼Pid
都會取代為元組{Pid,ProcessInfo,Node}
,其中ProcessInfo
是已註冊的程序名稱、其全域註冊的名稱或其初始函式。若要關閉此功能,請設定PI = false
。{shell, ShellSpec}
- 表示追蹤訊息將在追蹤程序接收到時列印在主控台上。這表示追蹤用戶端{local, File}
。如果ShellSpec
為only
(而非true
),則不會儲存任何追蹤記錄。shell
-{shell, true}
的捷徑。timer
- 表示追蹤將在MSec
毫秒後自動停止。如果指定,StopOpts
會傳遞至命令ttb:stop/1
(預設值為[]
)。請注意,時序是近似的,因為始終存在與網路通訊相關的延遲。計時器會在發出ttb:p/2
後開始,因此您可以事先設定追蹤模式。overload_check
- 允許在追蹤下的節點上啟用過載檢查。每MSec
毫秒執行一次Module:Function(check)
。如果檢查傳回true
,則會在指定的節點上停用追蹤。Module:Function
必須能夠處理至少三個原子:init
、check
和stop
。init
和stop
允許您初始化和清除檢查環境。當節點過載時,無法從
ttb:tp/2,3,4
系列發出ttb:p/2
或任何命令,因為這會導致追蹤狀態不一致(不同節點上的追蹤規格不同)。flush
- 定期刷新所有檔案追蹤埠用戶端(請參閱dbg:flush_trace_port/1
)。啟用時,緩衝區將每MSec
毫秒釋放一次。此選項不允許使用{file, {local, File}}
追蹤。{resume, FetchTimeout}
- 啟用自動恢復功能。啟用時,遠端節點會在重新啟動時嘗試重新連線至控制節點。此功能需要啟動應用程式 Runtime_Tools(因此,如果追蹤的節點使用嵌入式 Erlang 執行,則必須存在於.boot
指令碼中)。如果這不可能,可以使用rpc:call/4
遠端啟動Runtime_Tools
來手動執行恢復。ttb
會嘗試從重新連線的節點提取所有記錄,然後再重新初始化追蹤。這必須在FetchTimeout
毫秒內完成,否則會中止。預設情況下,自動啟動資訊會儲存在每個節點上名為
ttb_autostart.bin
的檔案中。如果不需要這樣做(例如,在無碟節點上),則可以透過為應用程式 Runtime_Tools 指定環境變數ttb_autostart_module
,提供自訂模組來處理自動啟動資訊的儲存和擷取。模組必須回應下列 APIwrite_config(Data) -> ok
- 儲存提供的資料,以便日後擷取。請務必瞭解,所使用的資料儲存體不得受到節點崩潰的影響。read_config() -> {ok, Data} | {error, Error}
- 擷取使用write_config(Data)
儲存的組態。delete_config() -> ok
- 刪除使用write_config(Data)
儲存的設定。請注意,在此呼叫之後,任何後續對read_config
的呼叫都必須返回{error, Error}
。
resume
表示預設的FetchTimeout
,為 10 秒。
-spec write_config(ConfigFile, Config) -> Result when ConfigFile :: file:filename(), Config :: all | [integer()] | [mfas()], Result :: ok | {error, term()}.
-spec write_config(ConfigFile, Config, Opts) -> Result when ConfigFile :: file:filename(), Config :: all | [integer()] | [mfas()], Opts :: Opt | [Opt], Opt :: append, Result :: ok | {error, term()}.
建立或擴充設定檔,該設定檔可用於稍後還原特定組態。
設定檔的內容可以從歷史記錄中擷取,也可以直接指定為 {Mod,Func,Args}
的列表。
如果整個歷史記錄都要儲存在設定檔中,則 Config
必須為 all
。如果只儲存歷史記錄中選定的條目,則 Config
必須是一個整數列表,指向要儲存的條目。
如果未指定 Opts
或為 []
,則會刪除 ConfigFile
並建立新檔案。 如果 Opts = [append]
,則不會刪除 ConfigFile
。新的資訊會附加在檔案末尾。
-spec write_trace_info(Key :: term(), Info) -> ok when Info :: Data :: term() | fun(() -> Data :: term()).
檔案 .ti
包含 {Key,ValueList}
元組。此函式會將 Data
新增至與 Key
相關聯的 ValueList
。使用此函式寫入的所有資訊都包含在對格式處理器的呼叫中。