et_contents_viewer.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 591 行 · 第 1/2 页

ERL
591
字号
            First = et_collector:make_key(S#state.event_order, E),            Mode  = {search_actors, forward, First, [From, To]},            send_viewer_event(S, {mode, Mode}),            {noreply, S};        'r' ->            E     = S#state.filtered_event,            From  = E#event.from,            To    = E#event.to,            First = et_collector:make_key(S#state.event_order, E),            Mode  = {search_actors, reverse, First, [From, To]},            send_viewer_event(S, {mode, Mode}),            {noreply, S};        'a' ->            send_viewer_event(S, {mode, all}),            {noreply, S};        0 ->            case lists:keysearch(collector, #filter.name, S#state.filters) of                {value, F} when record(F, filter) ->                    ChildState= S#state{active_filter = F#filter.name},                    case gen_server:start_link(?MODULE, [ChildState], []) of                        {ok, Pid} when S#state.parent_pid /= self() ->                            unlink(Pid);                        _ ->                            ignore                    end;                false ->                    ignore            end,            {noreply, S};        Int when integer(Int), Int > 0, Int =< 9 ->            case catch lists:nth(Int, S#state.filters) of                F when record(F, filter) ->                    ChildState= S#state{active_filter = F#filter.name},                    case gen_server:start_link(?MODULE, [ChildState], []) of                        {ok, Pid} when S#state.parent_pid /= self() ->                            unlink(Pid);                        _ ->                            ignore                    end;                {'EXIT', _} ->                    ignore            end,            {noreply, S};        'Shift_L' ->            {noreply, S};        'Shift_R' ->            {noreply, S};        'Caps_Lock' ->            {noreply, S};        _ ->            io:format("~p: ignored: ~p~n", [?MODULE, KeySym]),            {noreply, S}    end;handle_info({gs, _Obj, configure, [], [W, H | _]}, S) ->    gs:config(S#state.packer, [{width, W},{height, H}]),    S2 = S#state{width = W, height = H},    {noreply, S2};handle_info({'EXIT', Pid, Reason}, S) ->    if        Pid == S#state.parent_pid ->            unlink(Pid),            {stop, Reason, S};        true ->            {noreply, S}    end;handle_info(Info, S) ->    ok = error_logger:format("~p(~p): handle_info(~p, ~p)~n",                             [?MODULE, self(), Info, S]),    {noreply, S}.%%----------------------------------------------------------------------%% Func: terminate/2%% Purpose: Shutdown the server%% Returns: any (ignored by gen_server)%%----------------------------------------------------------------------terminate(_Reason, _S) ->    ignore.%%----------------------------------------------------------------------%% Func: code_change/3%% Purpose: Convert process state when code is changed%% Returns: {ok, NewState}%%----------------------------------------------------------------------code_change(_OldVsn, S, _Extra) ->    {ok, S}.%%%----------------------------------------------------------------------%%% Handle graphics%%%----------------------------------------------------------------------create_window(S) ->    H = S#state.height,    W = S#state.width,    Name = S#state.active_filter,    Title = lists:concat([?MODULE, " (filter: ", Name, ")"]),    WinOpt = [{title, Title}, {configure, true},              {width, W}, {height, H}],    GS  = gs:start(),    Win = gs:window(GS, WinOpt),    Bar = gs:menubar(Win, []),    create_file_menu(Bar),    PackerOpt = [{packer_x, [{stretch, 1}]},                 {packer_y, [{stretch, 1}, {fixed, 25}]},                 {x, 0}, {y, 25}],    Packer = gs:frame(Win, PackerOpt),    EditorOpt = [{pack_xy, {1, 1}}, {vscroll, right}, {hscroll, bottom},                 {wrap, none},                 {bg, lightblue},  {font, {courier, 12}}],    Editor = gs:editor(Packer, EditorOpt),    FilteredEvent = config_editor(Editor, S),    S2 = S#state{win = Win, packer = Packer, filtered_event = FilteredEvent},    create_hide_menu(Bar, S2),    create_search_menu(Bar, S2),    create_filter_menu(Bar, S#state.filters),    gs:config(Packer, [{width, W}, {height, H}]),    gs:config(Win, [{map,true}, {keypress, true}]),    S2.create_file_menu(Bar) ->    Button = gs:menubutton(Bar,  [{label, {text, "File"}}]),    Menu  = gs:menu(Button, []),    gs:menuitem(close, Menu,     [{label, {text,"Close (c)"}}]),    gs:menuitem(save, Menu,      [{label, {text,"Save"}}]).create_filter_menu(Bar, Filters) ->    Button = gs:menubutton(Bar, [{label, {text, "Filters"}}]),    Menu  = gs:menu(Button, []),    gs:menuitem(Menu, [{label, {text, "Select Filter"}}, {bg, lightblue}, {enable, false}]),    gs:menuitem(Menu, [{itemtype, separator}]),    Item = fun(F, N) when F#filter.name == collector->                   Label = lists:concat([pad_string(F#filter.name, 20), "(0)"]),                   gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),                   N + 1;              (F, N) ->                   Name = F#filter.name,                   Label = lists:concat([pad_string(Name, 20), "(", N, ")"]),                   gs:menuitem(Menu, [{label, {text, Label}}, {data, F}]),                   N + 1           end,    Filters2 = lists:keysort(#filter.name, Filters),    lists:foldl(Item, 1, Filters2),    Menu.create_hide_menu(Bar, S) ->    Button = gs:menubutton(Bar,  [{label, {text, "Hide"}}]),    Menu   = gs:menu(Button, []),    E      = S#state.filtered_event,    From   = E#event.from,    To     = E#event.to,    if        S#state.viewer_pid == undefined ->            ignore;        From == To ->            gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem({hide, [From]},     Menu, [{label, {text,"From=To (f|t|b)"}}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem({show, [From]},     Menu, [{label, {text,"From=To (F|T|B)"}}]);        true ->            gs:menuitem(Menu, [{label, {text, "Hide actor in Viewer "}}, {bg, lightblue}, {enable, false}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem({hide, [From]},     Menu, [{label, {text,"From (f)"}}]),            gs:menuitem({hide, [To]},       Menu, [{label, {text,"To   (t)"}}]),            gs:menuitem({hide, [From, To]}, Menu, [{label, {text,"Both (b)"}}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem(Menu, [{label, {text, "Show actor in Viewer "}}, {bg, lightblue}, {enable, false}]),            gs:menuitem(Menu, [{itemtype, separator}]),            gs:menuitem({show, [From]},     Menu, [{label, {text,"From (F)"}}]),            gs:menuitem({show, [To]},       Menu, [{label, {text,"To   (T)"}}]),            gs:menuitem({show, [From, To]}, Menu, [{label, {text,"Both (B)"}}])    end.create_search_menu(Bar, S) ->    Button = gs:menubutton(Bar,  [{label, {text, "Search"}}]),    Menu   = gs:menu(Button, []),    E      = S#state.filtered_event,    From   = E#event.from,    To     = E#event.to,    gs:menuitem(Menu, [{label, {text, "Search in Viewer "}},                       {bg, lightblue}, {enable, false}]),    gs:menuitem(Menu, [{itemtype, separator}]),    if        S#state.viewer_pid == undefined ->            S;        From == To  ->            Key = et_collector:make_key(S#state.event_order, E),            ModeS = {search_actors, forward, Key, [From]},            ModeR = {search_actors, reverse, Key, [From]},            gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event   (s)"}}]),            gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event   (r)"}}]);        true ->            Key = et_collector:make_key(S#state.event_order, E),            ModeS = {search_actors, forward, Key, [From, To]},            ModeR = {search_actors, reverse, Key, [From, To]},            gs:menuitem({mode, ModeS}, Menu, [{label, {text,"Forward from this event   (s)"}}]),            gs:menuitem({mode, ModeR}, Menu, [{label, {text,"Reverse from this event   (r)"}}])    end,    gs:menuitem({mode, all}, Menu,   [{label, {text,"Abort search. Display all (a)"}}]).config_editor(Editor, S) ->    Event = S#state.event,    Name = S#state.active_filter,    {value, F} = lists:keysearch(Name, #filter.name, S#state.filters),    FilterFun = F#filter.function,    case catch FilterFun(Event) of        true ->            do_config_editor(Editor, Event, lightblue, S#state.event_order);        {true, Event2} when record(Event2, event) ->            do_config_editor(Editor, Event2, lightblue, S#state.event_order);        false ->            do_config_editor(Editor, Event, red, S#state.event_order);        Bad ->            Contents = {bad_filter, Name, Bad},            BadEvent = Event#event{contents = Contents},            do_config_editor(Editor, BadEvent, red, S#state.event_order)    end.do_config_editor(Editor, Event, Colour, TsKey) ->    String = event_to_string(Event, TsKey),    gs:config(Editor, {insert, {'end', String}}),    gs:config(Editor, {enable, false}),    gs:config(Editor, {bg, Colour}),    Event.%%%----------------------------------------------------------------------%%% String handling%%%----------------------------------------------------------------------term_to_string(Term) ->    case catch io_lib:format("~s", [Term]) of        {'EXIT', _} -> io_lib:format("~p", [Term]);        GoodString  -> GoodString    end.now_to_string({Mega, Sec, Micro} = Now)  when integer(Mega), integer(Sec), integer(Micro) ->    {{Y, Mo, D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),    lists:concat([Y, "-", Mo, "-", D, " ", H, ".", Mi, ".", S, ".", Micro]);now_to_string(Other) ->    term_to_string(Other).event_to_string(Event, TsKey) ->    ReportedTs = Event#event.trace_ts,    ParsedTs   = Event#event.event_ts,    Deep =         ["DETAIL LEVEL: ", term_to_string(Event#event.detail_level),         "\nLABEL:        ", term_to_string(Event#event.label),         case Event#event.from == Event#event.to of             true ->                 ["\nACTOR:        ", term_to_string(Event#event.from)];             false ->                 ["\nFROM:         ", term_to_string(Event#event.from),                  "\nTO:           ", term_to_string(Event#event.to)]         end,         case ReportedTs == ParsedTs of             true ->                 ["\nPARSED:       ", now_to_string(ParsedTs)];             false ->                 case TsKey of                     trace_ts ->                         ["\nTRACE_TS:     ", now_to_string(ReportedTs),                          "\nEVENT_TS:     ", now_to_string(ParsedTs)];                     event_ts ->                         ["\nEVENT_TS:     ", now_to_string(ParsedTs),                          "\nTRACE_TS:     ", now_to_string(ReportedTs)]                 end         end,         "\nCONTENTS:\n\n", term_to_string(Event#event.contents)],    lists:flatten(Deep).pad_string(Atom, MinLen) when atom(Atom) ->    pad_string(atom_to_list(Atom), MinLen);pad_string(String, MinLen) when integer(MinLen), MinLen >= 0 ->    Len = length(String),    case Len >= MinLen of        true ->            String;        false ->            String ++ lists:duplicate(MinLen - Len, $ )    end.send_viewer_event(S, Event)  ->    case S#state.viewer_pid of        ViewerPid when pid(ViewerPid) ->            ViewerPid ! {et, Event};        undefined  ->            ignore    end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?