|
|
@ -111,13 +111,6 @@ |
|
|
|
|
|
|
|
-type requestId() :: term(). |
|
|
|
|
|
|
|
-record(handler, { |
|
|
|
module :: atom(), |
|
|
|
id = false, |
|
|
|
state, |
|
|
|
supervised = false :: 'false' | pid() |
|
|
|
}). |
|
|
|
|
|
|
|
-record(epmHer, { |
|
|
|
epmId = undefined :: term(), |
|
|
|
epmM :: atom(), |
|
|
@ -238,7 +231,7 @@ add_epm(EpmSrv, EpmHandler, Args) -> |
|
|
|
|
|
|
|
-spec add_sup_epm(serverRef(), epmHandler(), term()) -> term(). |
|
|
|
add_sup_epm(EpmSrv, EpmHandler, Args) -> |
|
|
|
epmRpc(EpmSrv, {'$addSupEpm', EpmHandler, Args}). |
|
|
|
epmRpc(EpmSrv, {'$addSupEpm', EpmHandler, Args, self()}). |
|
|
|
|
|
|
|
-spec del_epm(serverRef(), epmHandler(), term()) -> term(). |
|
|
|
del_epm(EpmSrv, EpmHandler, Args) -> |
|
|
@ -578,17 +571,6 @@ handleEpmCR(Result, EpmHers, #epmHer{epmId = EpmId} = EpmHer, Event, From) -> |
|
|
|
{maps:remove(EpmId, EpmHers), false} |
|
|
|
end. |
|
|
|
|
|
|
|
epmTerminate(#epmHer{epmM = EpmM, epmS = State} = EpmHer, Args, LastIn, Reason) -> |
|
|
|
case erlang:function_exported(EpmM, terminate, 2) of |
|
|
|
true -> |
|
|
|
Res = (catch EpmM:terminate(Args, State)), |
|
|
|
reportTerminate(EpmHer, Reason, Args, LastIn, Res), |
|
|
|
Res; |
|
|
|
false -> |
|
|
|
reportTerminate(EpmHer, Reason, Args, LastIn, ok), |
|
|
|
ok |
|
|
|
end. |
|
|
|
|
|
|
|
reportTerminate(EpmHer, crash, {error, Why}, LastIn, _) -> |
|
|
|
reportTerminate2(EpmHer, Why, LastIn); |
|
|
|
%% How == normal | shutdown | {swapped, NewHandler, NewSupervisor} |
|
|
@ -611,7 +593,7 @@ report_error(_EpmHer, {swapped, _, _}, _, _) -> ok; |
|
|
|
report_error(#epmHer{epmId = EpmId, epmM = EpmM}, Reason, State, LastIn) -> |
|
|
|
?LOG_ERROR( |
|
|
|
#{ |
|
|
|
label => {gen_ipc, epm_terminate}, |
|
|
|
label => {gen_emm, epm_terminate}, |
|
|
|
handler => {EpmId, EpmM}, |
|
|
|
name => undefined, |
|
|
|
last_message => LastIn, |
|
|
@ -620,11 +602,11 @@ report_error(#epmHer{epmId = EpmId, epmM = EpmM}, Reason, State, LastIn) -> |
|
|
|
}, |
|
|
|
#{ |
|
|
|
domain => [otp], |
|
|
|
report_cb => fun gen_ipc:epm_log/1, |
|
|
|
report_cb => fun gen_emm:epm_log/1, |
|
|
|
error_logger => #{tag => error} |
|
|
|
}). |
|
|
|
|
|
|
|
epm_log(#{label := {gen_ipc, epm_terminate}, handler := Handler, name := SName, last_message := LastIn, state := State, reason := Reason}) -> |
|
|
|
epm_log(#{label := {gen_emm, epm_terminate}, handler := Handler, name := SName, last_message := LastIn, state := State, reason := Reason}) -> |
|
|
|
Reason1 = |
|
|
|
case Reason of |
|
|
|
{'EXIT', {undef, [{M, F, A, L} | MFAs]}} -> |
|
|
@ -644,12 +626,12 @@ epm_log(#{label := {gen_ipc, epm_terminate}, handler := Handler, name := SName, |
|
|
|
_ -> |
|
|
|
Reason |
|
|
|
end, |
|
|
|
{"** gen_ipc emp handler ~p crashed.~n" |
|
|
|
{"** gen_emm emp handler ~p crashed.~n" |
|
|
|
"** Was installed in ~tp~n" |
|
|
|
"** Last event was: ~tp~n" |
|
|
|
"** When handler state == ~tp~n" |
|
|
|
"** Reason == ~tp~n", [Handler, SName, LastIn, State, Reason1]}; |
|
|
|
epm_log(#{label := {gen_ipc, no_handle_info}, module := Module, message := Msg}) -> |
|
|
|
epm_log(#{label := {gen_emm, no_handle_info}, module := Module, message := Msg}) -> |
|
|
|
{"** Undefined handle_info in ~tp~n" |
|
|
|
"** Unhandled message: ~tp~n", [Module, Msg]}. |
|
|
|
|
|
|
@ -725,45 +707,22 @@ do_unlink(Parent, MSL) -> |
|
|
|
end, |
|
|
|
MSL). |
|
|
|
|
|
|
|
%% First terminate the supervised (if exists) handlers and |
|
|
|
%% then inform other handlers. |
|
|
|
%% We do not know if any handler really is interested but it |
|
|
|
%% may be so ! |
|
|
|
handle_exit(From, Reason, MSL, SName) -> |
|
|
|
MSL1 = terminate_supervised(From, Reason, MSL, SName), |
|
|
|
{_, MSL2} = server_notify({'EXIT', From, Reason}, handle_info, MSL1, SName), |
|
|
|
MSL2. |
|
|
|
|
|
|
|
terminate_supervised(Pid, Reason, MSL, SName) -> |
|
|
|
F = fun(Ha) when Ha#handler.supervised =:= Pid -> |
|
|
|
do_terminate(Ha#handler.module, |
|
|
|
Ha, |
|
|
|
{stop, Reason}, |
|
|
|
Ha#handler.state, |
|
|
|
{parent_terminated, {Pid, Reason}}, |
|
|
|
SName, |
|
|
|
shutdown), |
|
|
|
false; |
|
|
|
(_) -> |
|
|
|
true |
|
|
|
end, |
|
|
|
lists:filter(F, MSL). |
|
|
|
|
|
|
|
%%----------------------------------------------------------------- |
|
|
|
%% Callback functions for system messages handling. |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
system_continue(Parent, Debug, [ServerName, MSL, HibernateAfterTimeout, Hib]) -> |
|
|
|
loopEntry(Parent, ServerName, MSL, HibernateAfterTimeout, Debug, Hib). |
|
|
|
system_continue(Parent, Debug, [ServerName, HibernateAfterTimeout, EpmHers, Hib]) -> |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, Hib). |
|
|
|
|
|
|
|
-spec system_terminate(_, _, _, [_]) -> no_return(). |
|
|
|
system_terminate(Reason, Parent, _Debug, [ServerName, EpmHers, _HibernateAfterTimeout, _Hib]) -> |
|
|
|
terminate_server(Reason, Parent, ServerName, EpmHers). |
|
|
|
system_terminate(Reason, Parent, _Debug, [ServerName, _HibernateAfterTimeout, EpmHers, _Hib]) -> |
|
|
|
terminate_server(Reason, Parent, ServerName, EpmHers). |
|
|
|
|
|
|
|
%%----------------------------------------------------------------- |
|
|
|
%% Module here is sent in the system msg change_code. It specifies |
|
|
|
%% which module should be changed. |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
system_code_change([ServerName, MSL, HibernateAfterTimeout, Hib], Module, OldVsn, Extra) -> |
|
|
|
system_code_change([ServerName, HibernateAfterTimeout, EpmHers, Hib], Module, OldVsn, Extra) -> |
|
|
|
MSL1 = lists:zf(fun(H) when H#handler.module =:= Module -> |
|
|
|
{ok, NewState} = |
|
|
|
Module:code_change(OldVsn, |
|
|
@ -808,309 +767,6 @@ print_event(Dev, {in, Msg}, Name) -> |
|
|
|
print_event(Dev, Dbg, Name) -> |
|
|
|
io:format(Dev, "*DBG* ~tp : ~tp~n", [Name, Dbg]). |
|
|
|
|
|
|
|
|
|
|
|
%% server_add_handler(Handler, Args, MSL) -> {Ret, MSL'}. |
|
|
|
%% where MSL = [#handler{}] |
|
|
|
%% Ret goes to the top level MSL' is the new internal state of the |
|
|
|
%% event handler |
|
|
|
|
|
|
|
server_add_handler({Mod, Id}, Args, MSL) -> |
|
|
|
Handler = #handler{module = Mod, |
|
|
|
id = Id}, |
|
|
|
server_add_handler(Mod, Handler, Args, MSL); |
|
|
|
server_add_handler(Mod, Args, MSL) -> |
|
|
|
Handler = #handler{module = Mod}, |
|
|
|
server_add_handler(Mod, Handler, Args, MSL). |
|
|
|
|
|
|
|
server_add_handler(Mod, Handler, Args, MSL) -> |
|
|
|
case catch Mod:init(Args) of |
|
|
|
{ok, State} -> |
|
|
|
{false, ok, [Handler#handler{state = State} | MSL]}; |
|
|
|
{ok, State, hibernate} -> |
|
|
|
{true, ok, [Handler#handler{state = State} | MSL]}; |
|
|
|
Other -> |
|
|
|
{false, Other, MSL} |
|
|
|
end. |
|
|
|
|
|
|
|
%% Set up a link to the supervising process. |
|
|
|
%% (Ought to be unidirected links here, Erl5.0 !!) |
|
|
|
%% NOTE: This link will not be removed then the |
|
|
|
%% handler is removed in case another handler has |
|
|
|
%% own link to this process. |
|
|
|
server_add_sup_handler({Mod, Id}, Args, MSL, Parent) -> |
|
|
|
link(Parent), |
|
|
|
Handler = #handler{module = Mod, |
|
|
|
id = Id, |
|
|
|
supervised = Parent}, |
|
|
|
server_add_handler(Mod, Handler, Args, MSL); |
|
|
|
server_add_sup_handler(Mod, Args, MSL, Parent) -> |
|
|
|
link(Parent), |
|
|
|
Handler = #handler{module = Mod, |
|
|
|
supervised = Parent}, |
|
|
|
server_add_handler(Mod, Handler, Args, MSL). |
|
|
|
|
|
|
|
%% server_delete_handler(HandlerId, Args, MSL) -> {Ret, MSL'} |
|
|
|
|
|
|
|
server_delete_handler(HandlerId, Args, MSL, SName) -> |
|
|
|
case split(HandlerId, MSL) of |
|
|
|
{Mod, Handler, MSL1} -> |
|
|
|
{do_terminate(Mod, Handler, Args, |
|
|
|
Handler#handler.state, delete, SName, normal), |
|
|
|
MSL1}; |
|
|
|
error -> |
|
|
|
{{error, module_not_found}, MSL} |
|
|
|
end. |
|
|
|
|
|
|
|
%% server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, SN) -> MSL' |
|
|
|
%% server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, Sup, SN) -> MSL' |
|
|
|
|
|
|
|
server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, SName) -> |
|
|
|
{State2, Sup, MSL1} = split_and_terminate(Handler1, Args1, MSL, |
|
|
|
SName, Handler2, false), |
|
|
|
case s_s_h(Sup, Handler2, {Args2, State2}, MSL1) of |
|
|
|
{Hib, ok, MSL2} -> |
|
|
|
{Hib, ok, MSL2}; |
|
|
|
{Hib, What, MSL2} -> |
|
|
|
{Hib, {error, What}, MSL2} |
|
|
|
end. |
|
|
|
|
|
|
|
server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, Sup, SName) -> |
|
|
|
{State2, _, MSL1} = split_and_terminate(Handler1, Args1, MSL, |
|
|
|
SName, Handler2, Sup), |
|
|
|
case s_s_h(Sup, Handler2, {Args2, State2}, MSL1) of |
|
|
|
{Hib, ok, MSL2} -> |
|
|
|
{Hib, ok, MSL2}; |
|
|
|
{Hib, What, MSL2} -> |
|
|
|
{Hib, {error, What}, MSL2} |
|
|
|
end. |
|
|
|
|
|
|
|
s_s_h(false, Handler, Args, MSL) -> |
|
|
|
server_add_handler(Handler, Args, MSL); |
|
|
|
s_s_h(Pid, Handler, Args, MSL) -> |
|
|
|
server_add_sup_handler(Handler, Args, MSL, Pid). |
|
|
|
|
|
|
|
split_and_terminate(HandlerId, Args, MSL, SName, Handler2, Sup) -> |
|
|
|
case split(HandlerId, MSL) of |
|
|
|
{Mod, Handler, MSL1} -> |
|
|
|
OldSup = Handler#handler.supervised, |
|
|
|
NewSup = if |
|
|
|
not Sup -> OldSup; |
|
|
|
true -> Sup |
|
|
|
end, |
|
|
|
{do_terminate(Mod, Handler, Args, |
|
|
|
Handler#handler.state, swapped, SName, |
|
|
|
{swapped, Handler2, NewSup}), |
|
|
|
OldSup, |
|
|
|
MSL1}; |
|
|
|
error -> |
|
|
|
{error, false, MSL} |
|
|
|
end. |
|
|
|
|
|
|
|
%% server_notify(Event, Func, MSL, SName) -> MSL' |
|
|
|
|
|
|
|
server_notify(Event, Func, [Handler | T], SName) -> |
|
|
|
case server_update(Handler, Func, Event, SName) of |
|
|
|
{ok, Handler1} -> |
|
|
|
{Hib, NewHandlers} = server_notify(Event, Func, T, SName), |
|
|
|
{Hib, [Handler1 | NewHandlers]}; |
|
|
|
{hibernate, Handler1} -> |
|
|
|
{_Hib, NewHandlers} = server_notify(Event, Func, T, SName), |
|
|
|
{true, [Handler1 | NewHandlers]}; |
|
|
|
no -> |
|
|
|
server_notify(Event, Func, T, SName) |
|
|
|
end; |
|
|
|
server_notify(_, _, [], _) -> |
|
|
|
{false, []}. |
|
|
|
|
|
|
|
%% server_update(Handler, Func, Event, ServerName) -> Handler1 | no |
|
|
|
|
|
|
|
server_update(Handler1, Func, Event, SName) -> |
|
|
|
Mod1 = Handler1#handler.module, |
|
|
|
State = Handler1#handler.state, |
|
|
|
case catch Mod1:Func(Event, State) of |
|
|
|
{ok, State1} -> |
|
|
|
{ok, Handler1#handler{state = State1}}; |
|
|
|
{ok, State1, hibernate} -> |
|
|
|
{hibernate, Handler1#handler{state = State1}}; |
|
|
|
{swap_handler, Args1, State1, Handler2, Args2} -> |
|
|
|
do_swap(Mod1, Handler1, Args1, State1, Handler2, Args2, SName); |
|
|
|
remove_handler -> |
|
|
|
do_terminate(Mod1, Handler1, remove_handler, State, |
|
|
|
remove, SName, normal), |
|
|
|
no; |
|
|
|
{'EXIT', {undef, [{Mod1, handle_info, [_, _], _} | _]}} -> |
|
|
|
?LOG_WARNING(#{label => {gen_event, no_handle_info}, |
|
|
|
module => Mod1, |
|
|
|
message => Event}, |
|
|
|
#{domain => [otp], |
|
|
|
report_cb => fun gen_event:format_log/2, |
|
|
|
error_logger => |
|
|
|
#{tag => warning_msg, % warningmap?? |
|
|
|
report_cb => fun gen_event:format_log/1}}), |
|
|
|
{ok, Handler1}; |
|
|
|
Other -> |
|
|
|
do_terminate(Mod1, Handler1, {error, Other}, State, |
|
|
|
Event, SName, crash), |
|
|
|
no |
|
|
|
end. |
|
|
|
|
|
|
|
do_swap(Mod1, Handler1, Args1, State1, Handler2, Args2, SName) -> |
|
|
|
%% finalise the existing handler |
|
|
|
State2 = do_terminate(Mod1, Handler1, Args1, State1, |
|
|
|
swapped, SName, |
|
|
|
{swapped, Handler2, Handler1#handler.supervised}), |
|
|
|
{Mod2, Handler} = new_handler(Handler2, Handler1), |
|
|
|
case catch Mod2:init({Args2, State2}) of |
|
|
|
{ok, State2a} -> |
|
|
|
{ok, Handler#handler{state = State2a}}; |
|
|
|
Other -> |
|
|
|
report_terminate(Handler, crash, {error, Other}, SName, false), |
|
|
|
no |
|
|
|
end. |
|
|
|
|
|
|
|
new_handler({Mod, Id}, Handler1) -> |
|
|
|
{Mod, #handler{module = Mod, |
|
|
|
id = Id, |
|
|
|
supervised = Handler1#handler.supervised}}; |
|
|
|
new_handler(Mod, Handler1) -> |
|
|
|
{Mod, #handler{module = Mod, |
|
|
|
supervised = Handler1#handler.supervised}}. |
|
|
|
|
|
|
|
|
|
|
|
-spec split(handler(), [#handler{}]) -> |
|
|
|
{atom(), #handler{}, [#handler{}]} | 'error'. |
|
|
|
|
|
|
|
split(Ha, MSL) -> split(Ha, MSL, []). |
|
|
|
|
|
|
|
split({Mod, Id}, [Ha | T], L) when Ha#handler.module =:= Mod, |
|
|
|
Ha#handler.id =:= Id -> |
|
|
|
{Mod, Ha, lists:reverse(L, T)}; |
|
|
|
split(Mod, [Ha | T], L) when Ha#handler.module =:= Mod, |
|
|
|
not Ha#handler.id -> |
|
|
|
{Mod, Ha, lists:reverse(L, T)}; |
|
|
|
split(Ha, [H | T], L) -> |
|
|
|
split(Ha, T, [H | L]); |
|
|
|
split(_, [], _) -> |
|
|
|
error. |
|
|
|
|
|
|
|
%% server_call(Handler, Query, MSL, ServerName) -> |
|
|
|
%% {Reply, MSL1} |
|
|
|
|
|
|
|
server_call(Handler, Query, MSL, SName) -> |
|
|
|
case search(Handler, MSL) of |
|
|
|
{ok, Ha} -> |
|
|
|
case server_call_update(Ha, Query, SName) of |
|
|
|
{no, Reply} -> |
|
|
|
{false, Reply, delete(Handler, MSL)}; |
|
|
|
{{ok, Ha1}, Reply} -> |
|
|
|
{false, Reply, replace(Handler, MSL, Ha1)}; |
|
|
|
{{hibernate, Ha1}, Reply} -> |
|
|
|
{true, Reply, replace(Handler, MSL, Ha1)} |
|
|
|
end; |
|
|
|
false -> |
|
|
|
{false, {error, bad_module}, MSL} |
|
|
|
end. |
|
|
|
|
|
|
|
search({Mod, Id}, [Ha | _MSL]) when Ha#handler.module =:= Mod, |
|
|
|
Ha#handler.id =:= Id -> |
|
|
|
{ok, Ha}; |
|
|
|
search(Mod, [Ha | _MSL]) when Ha#handler.module =:= Mod, |
|
|
|
not Ha#handler.id -> |
|
|
|
{ok, Ha}; |
|
|
|
search(Handler, [_ | MSL]) -> |
|
|
|
search(Handler, MSL); |
|
|
|
search(_, []) -> |
|
|
|
false. |
|
|
|
|
|
|
|
delete({Mod, Id}, [Ha | MSL]) when Ha#handler.module =:= Mod, |
|
|
|
Ha#handler.id =:= Id -> |
|
|
|
MSL; |
|
|
|
delete(Mod, [Ha | MSL]) when Ha#handler.module =:= Mod, |
|
|
|
not Ha#handler.id -> |
|
|
|
MSL; |
|
|
|
delete(Handler, [Ha | MSL]) -> |
|
|
|
[Ha | delete(Handler, MSL)]; |
|
|
|
delete(_, []) -> |
|
|
|
[]. |
|
|
|
|
|
|
|
replace({Mod, Id}, [Ha | MSL], NewHa) when Ha#handler.module =:= Mod, |
|
|
|
Ha#handler.id =:= Id -> |
|
|
|
[NewHa | MSL]; |
|
|
|
replace(Mod, [Ha | MSL], NewHa) when Ha#handler.module =:= Mod, |
|
|
|
not Ha#handler.id -> |
|
|
|
[NewHa | MSL]; |
|
|
|
replace(Handler, [Ha | MSL], NewHa) -> |
|
|
|
[Ha | replace(Handler, MSL, NewHa)]; |
|
|
|
replace(_, [], NewHa) -> |
|
|
|
[NewHa]. |
|
|
|
|
|
|
|
%% server_call_update(Handler, Query, ServerName) -> |
|
|
|
%% {{Handler1, State1} | 'no', Reply} |
|
|
|
|
|
|
|
server_call_update(Handler1, Query, SName) -> |
|
|
|
Mod1 = Handler1#handler.module, |
|
|
|
State = Handler1#handler.state, |
|
|
|
case catch Mod1:handle_call(Query, State) of |
|
|
|
{ok, Reply, State1} -> |
|
|
|
{{ok, Handler1#handler{state = State1}}, Reply}; |
|
|
|
{ok, Reply, State1, hibernate} -> |
|
|
|
{{hibernate, Handler1#handler{state = State1}}, |
|
|
|
Reply}; |
|
|
|
{swap_handler, Reply, Args1, State1, Handler2, Args2} -> |
|
|
|
{do_swap(Mod1, Handler1, Args1, State1, Handler2, Args2, SName), Reply}; |
|
|
|
{remove_handler, Reply} -> |
|
|
|
do_terminate(Mod1, Handler1, remove_handler, State, |
|
|
|
remove, SName, normal), |
|
|
|
{no, Reply}; |
|
|
|
Other -> |
|
|
|
do_terminate(Mod1, Handler1, {error, Other}, State, |
|
|
|
Query, SName, crash), |
|
|
|
{no, {error, Other}} |
|
|
|
end. |
|
|
|
|
|
|
|
do_terminate(Mod, Handler, Args, State, LastIn, SName, Reason) -> |
|
|
|
case erlang:function_exported(Mod, terminate, 2) of |
|
|
|
true -> |
|
|
|
Res = (catch Mod:terminate(Args, State)), |
|
|
|
report_terminate(Handler, Reason, Args, State, LastIn, SName, Res), |
|
|
|
Res; |
|
|
|
false -> |
|
|
|
report_terminate(Handler, Reason, Args, State, LastIn, SName, ok), |
|
|
|
ok |
|
|
|
end. |
|
|
|
|
|
|
|
report_terminate(Handler, crash, {error, Why}, State, LastIn, SName, _) -> |
|
|
|
report_terminate(Handler, Why, State, LastIn, SName); |
|
|
|
report_terminate(Handler, How, _, State, LastIn, SName, _) -> |
|
|
|
%% How == normal | shutdown | {swapped, NewHandler, NewSupervisor} |
|
|
|
report_terminate(Handler, How, State, LastIn, SName). |
|
|
|
|
|
|
|
report_terminate(Handler, Reason, State, LastIn, SName) -> |
|
|
|
report_error(Handler, Reason, State, LastIn, SName), |
|
|
|
case Handler#handler.supervised of |
|
|
|
false -> |
|
|
|
ok; |
|
|
|
Pid -> |
|
|
|
Pid ! {gen_event_EXIT, handler(Handler), Reason}, |
|
|
|
ok |
|
|
|
end. |
|
|
|
|
|
|
|
report_error(_Handler, normal, _, _, _) -> ok; |
|
|
|
report_error(_Handler, shutdown, _, _, _) -> ok; |
|
|
|
report_error(_Handler, {swapped, _, _}, _, _, _) -> ok; |
|
|
|
report_error(Handler, Reason, State, LastIn, SName) -> |
|
|
|
?LOG_ERROR(#{label => {gen_event, terminate}, |
|
|
|
handler => handler(Handler), |
|
|
|
name => SName, |
|
|
|
last_message => LastIn, |
|
|
|
state => format_status(terminate, Handler#handler.module, |
|
|
|
get(), State), |
|
|
|
reason => Reason}, |
|
|
|
#{domain => [otp], |
|
|
|
report_cb => fun gen_event:format_log/2, |
|
|
|
error_logger => #{tag => error, |
|
|
|
report_cb => fun gen_event:format_log/1}}). |
|
|
|
|
|
|
|
%% format_log/1 is the report callback used by Logger handler |
|
|
|
%% error_logger only. It is kept for backwards compatibility with |
|
|
|
%% legacy error_logger event handlers. This function must always |
|
|
@ -1295,15 +951,10 @@ get_modules(MSL) -> |
|
|
|
%% Status information |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
format_status(Opt, StatusData) -> |
|
|
|
[PDict, SysState, Parent, _Debug, [ServerName, MSL, _HibernateAfterTimeout, _Hib]] = StatusData, |
|
|
|
Header = gen:format_status_header("Status for event handler", |
|
|
|
ServerName), |
|
|
|
FmtMSL = [MS#handler{state = format_status(Opt, Mod, PDict, State)} |
|
|
|
|| #handler{module = Mod, state = State} = MS <- MSL], |
|
|
|
[{header, Header}, |
|
|
|
{data, [{"Status", SysState}, |
|
|
|
{"Parent", Parent}]}, |
|
|
|
{items, {"Installed handlers", FmtMSL}}]. |
|
|
|
[PDict, SysState, Parent, _Debug, [ServerName, _HibernateAfterTimeout, EpmHers, _Hib]] = StatusData, |
|
|
|
Header = gen:format_status_header("Status for gen_emm handler", ServerName), |
|
|
|
FmtMSL = [MS#handler{state = format_status(Opt, Mod, PDict, State)} || #handler{module = Mod, state = State} = MS <- MSL], |
|
|
|
[{header, Header}, {data, [{"Status", SysState}, {"Parent", Parent}]}, {items, {"Installed handlers", FmtMSL}}]. |
|
|
|
|
|
|
|
format_status(Opt, Mod, PDict, State) -> |
|
|
|
case erlang:function_exported(Mod, format_status, 2) of |
|
|
|