📄 et_demo.erl
字号:
%%%----------------------------------------------------------------------%%% File : et_demo.erl%%% Author : H}kan Mattsson <hakan@erix.ericsson.se>%%% Purpose : Provide some event trace filter examples.%%% Created : 09 Oct 2001 by H}kan Mattsson <hakan@erix.ericsson.se>%%%-----------------------------------------------------------------------module(et_demo).-author('hakan@erix.ericsson.se').-export([sim_trans/0, mgr_actors/1, live_trans/0, start/0, start/1, filters/0, trace_mnesia/0]).-include_lib("et/include/et.hrl").%%----------------------------------------------------------------------%sim_transsim_trans() -> Options = [{dict_insert, {filter, mgr_actors}, fun mgr_actors/1}], {ok, Viewer} = et_viewer:start_link(Options), Collector = et_viewer:get_collector_pid(Viewer), et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer, "Start outer transaction"), et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid, "New transaction id is 4711"), et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock, "Acquire write lock for {my_tab, key}"), et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted, "You got the write lock for {my_tab, key}"), et_collector:report_event(Collector, 60, my_shell, do_commit, "Perform transaction commit"), et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid, "Release all locks for transaction 4711"), et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction, "End of outer transaction"), et_collector:report_event(Collector, 20, my_shell, end_outer, "Transaction returned {atomic, ok}").%sim_trans%mgr_actorsmgr_actors(E) when record(E, event) -> Actor = fun(A) -> case A of mnesia_tm -> trans_mgr; mnesia_locker -> lock_mgr; _ -> A end end, {true, E#event{from = Actor(E#event.from), to = Actor(E#event.to), contents = [{orig_from, E#event.from}, {orig_to, E#event.to}, {orig_contents, E#event.contents}]}}.%mgr_actors%%----------------------------------------------------------------------%startstart() -> start([]).start(ExtraOptions) -> Options = [{trace_global, true}, {parent_pid, undefined}, {max_actors, infinity}, {max_events, 1000}, {active_filter, module_as_actor}], et_viewer:start_link(filters() ++ Options ++ ExtraOptions).%start%%----------------------------------------------------------------------%live_translive_trans() -> et_demo:start([{title, "Mnesia tracer"}, {hide_actions, true}, {active_filter, named_process_info_nolink}]), mnesia:start(), mnesia:create_table(my_tab, [{ram_copies, [node()]}]), et_demo:trace_mnesia(), register(my_shell, self()), mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).%live_trans%%----------------------------------------------------------------------%trace_mnesiatrace_mnesia() -> Modules = mnesia:ms(), Spec = [{message, {caller}}, {return_trace}], Flags = [send, 'receive', procs, timestamp], dbg:p(all, [call, timestamp]), [dbg:tpl(M, [{'_', [], Spec}]) || M <- Modules], LocallyRunningServers = [M || M <- Modules, whereis(M) /= undefined], [dbg:p(whereis(RS), Flags) || RS <- LocallyRunningServers], dbg:p(self(), Flags), LocallyRunningServers.%trace_mnesia%%----------------------------------------------------------------------%% Filter funs returns false, true or {true, NewEvent}%%----------------------------------------------------------------------%filtersfilters() -> [{dict_insert, {filter, module_as_actor}, fun module_as_actor/1}, {dict_insert, {filter, plain_process_info}, fun plain_process_info/1}, {dict_insert, {filter, plain_process_info_nolink}, fun plain_process_info_nolink/1}, {dict_insert, {filter, named_process_info}, fun named_process_info/1}, {dict_insert, {filter, named_process_info_nolink}, fun named_process_info_nolink/1}, {dict_insert, {filter, node_process_info}, fun node_process_info/1}, {dict_insert, {filter, node_process_info_nolink}, fun node_process_info_nolink/1}, {dict_insert, {filter, application_as_actor}, fun application_as_actor/1} ].%filters%module_as_actormodule_as_actor(E) when record(E, event) -> case lists:keysearch(mfa, 1, E#event.contents) of {value, {mfa, {M, F, _A}}} -> case lists:keysearch(pam_result, 1, E#event.contents) of {value, {pam_result, {M2, _F2, _A2}}} -> {true, E#event{label = F, from = M2, to = M}}; _ -> {true, E#event{label = F, from = M, to = M}} end; _ -> false end.%module_as_actor%%----------------------------------------------------------------------%plain_process_infoplain_process_info(E) when record(E, event) -> case E#event.label of send -> true; send_to_non_existing_process -> true; 'receive' -> true; spawn -> true; exit -> true; link -> true; unlink -> true; getting_linked -> true; {seq_send, _Label} -> true; {seq_receive, _Label} -> true; {seq_print, _Label} -> true; {drop, _N} -> true; _ -> false end.%plain_process_info%plain_process_info_nolinkplain_process_info_nolink(E) when record(E, event) -> (E#event.label /= link) and (E#event.label /= unlink) and (E#event.label /= getting_linked) and plain_process_info(E). %plain_process_info_nolink%%----------------------------------------------------------------------named_process_info(E) when record(E, event) -> case plain_process_info(E) of true -> {true, E#event{to = pid_to_name(E#event.to), from = pid_to_name(E#event.from), label = msg_to_label(E)}}; false -> false end.named_process_info_nolink(E) when record(E, event) -> case plain_process_info_nolink(E) of true -> {true, E#event{to = pid_to_name(E#event.to), from = pid_to_name(E#event.from), label = msg_to_label(E)}}; false -> false end.pid_to_name(Pid) when pid(Pid) -> case process_info(Pid, registered_name) of {registered_name, Name} -> Name; _ -> Pid end;pid_to_name({Name, Node}) when Node == node() -> Name;pid_to_name(Other) -> Other.%%----------------------------------------------------------------------node_process_info(E) when record(E, event) -> case plain_process_info(E) of true -> {true, E#event{to = pid_to_node(E#event.to), from = pid_to_node(E#event.from), label = msg_to_label(E)}}; false -> false end.node_process_info_nolink(E) when record(E, event) -> case plain_process_info_nolink(E) of true -> {true, E#event{to = pid_to_node(E#event.to), from = pid_to_node(E#event.from), label = msg_to_label(E)}}; false -> false end.pid_to_node(Pid) when pid(Pid) -> node(Pid);pid_to_node(Name) when atom(Name) -> node();pid_to_node({_Name, Node}) when atom(Node) -> Node.%%----------------------------------------------------------------------application_as_actor(E) when record(E, event) -> {true, E#event{to = pid_to_application(E#event.to), from = pid_to_application(E#event.from), label = msg_to_label(E)}}.pid_to_application(Pid) when pid(Pid) -> case application:get_application(Pid) of {ok, Name} -> Name; _ -> "UNKNOWN" end.%%----------------------------------------------------------------------msg_to_label(E) when record(E, event) -> case lists:keysearch(msg, 1, E#event.contents) of {value, {msg, Msg}} -> mnesia_msg_to_label(Msg, E#event.label); false -> E#event.label end.mnesia_msg_to_label(Msg, Label) -> case Msg of {mnesia_tm, _Node, Reply} -> case Reply of ok -> ok; store_erased -> store_erased; unblocked -> unblocked; {_From, _Ref, start_outer} -> start_outer; {aborted, _Tid} -> aborted; {committed, _Tid} -> committed; {dirty_res, _Res} -> dirty_res; {error, _Reason} -> error; {info, _Part, _Coord} -> info; {mnesia_tm, _Node, {'EXIT', _Reason}} -> 'EXIT'; {mnesia_tm, _Node, {dirty_res, _Reply}} -> dirty_res; {new_store, _Etab} -> new_store; {new_tid, _Tid, _Etab} -> new_tid; {ok, _Name, _IgnoreNew, _Node} -> ok; {restarted, _Tid} -> restarted; {vote_yes, _Tid, _Self} -> vote_yes; {vote_yes, _Tid} -> vote_yes; {acc_pre_commit, _Tid, _Self, _Expect} -> acc_pre_commit; {schema_commit, _Tid, _Self} -> schema_commit; {vote_no, _Tid, _Reason} -> vote_no end; {'$gen_cast',allow_garb} -> allow_garb; {'$gen_cast', {release_schema_commit_lock, _Pid}} -> release_schema_commit_lock; {'$gen_call', _Ref, {mktab, _Name,_Args}} -> mktab; {'$gen_call', _Ref, wait_for_schema_commit_lock} -> wait_for_schema_commit_lock; {'$gen_call', _Ref, {set_lock, _Key}} -> set_global_lock; {'$gen_call', _Ref, {del_lock, _Key}} -> del_global_lock; {'$gen_call', _Ref, {what_happened, _Decision, _Tid}} -> what_happened; {async_dump_log, _Reason} -> async_dump_log; check_overload -> check_overload; {dumper_done, _Pid, dumped} -> dumper_done; garb_decisions -> garb_decisions; timeout -> timeout; {mnesia_locker, _Node, granted} -> granted; {mnesia_locker, _Node, {granted, _Lookup}} -> granted; {'EXIT', _Pid, _Reason} -> 'EXIT'; {_From, info} -> info; {_From, start_outer} -> start_outer; {_From, {add_store, _Tid}} -> add_store; {_From, {ask_commit, _Prot, _Tid, _Commit, _DiscNs, _RamNs}} -> ask_commit; {_From, {async_dirty, _Tid, _Commit, _Tab}} -> async_dirty; {_From, {block_tab, _Tab}} -> block_tab; {_From, {del_store, _Tid, _Current, _Obsolete, _Prop}} -> del_store; {_From, {prepare_checkpoint, _Cp}} ->prepare_checkpoint; {_From, {read, _Tid, _Oid}} -> try_read_lock; {_From, {read_write, _Tid, _Oid}} -> try_read_write_lock; {_From, {restart, _Tid, _Store}} -> restart; {_From, {sync_dirty, _Tid, _Commit, _Tab}} -> sync_dirty; {_From, {unblock_me, _Tab}} -> unblock_me; {_From, {unblock_tab, _Tab}} -> unblock_tab; {_From, {write, _Tid, _Oid}} -> try_write_lock; {_Tid, committed} -> committed; {_Tid, do_commit} -> do_commit; {_Tid, pre_commit} -> pre_commit; {_Tid, simple_commit} -> simple_commit; {_Tid, {do_abort, _Reason}} -> do_abort; {activity_ended, _, _Pid} -> activity_ended; {ask_commit, _Protocol, _Tid, _Bin, _DiscNs, _RamNs} -> ask_commit; {delete_transaction, _Tid} -> delete_transaction; {mnesia_down, _Node} -> mnesia_down; {release_tid, _Tid} -> release_tid; {sync_trans_serial, _Tid} -> sync_trans_serial; {system, _From, _Msg} -> system; {transaction_done, _Res, _Pid} -> transaction_done; {_Tid, {do_abort, _Reason}} -> do_abort; {_Ref, granted} -> granted; _ -> Label end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -