[erlang-questions] Who called my gen_server?
Valentin Micic
v@REDACTED
Thu Apr 27 11:30:51 CEST 2017
> Or, can I log all rpc_call(s) calling my gen_server?
>
> /Frank
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
General comments about appropriateness of rpc notwithstanding….
Consider following statements (you may run them from the shell):
(tcap2@REDACTED)225> f(REX), REX=whereis(rex).
<0.12.0>
(tcap2@REDACTED)226> unregister( rex ).
true
(tcap2@REDACTED)227> catch register( rex, self() ).
true
Then, you could go to the remote node's shell and run, say:
(tcap3@REDACTED)3> rpc:call( tcap2@REDACTED, erlang, now, [], 1000 ).
(NOTE 1: the caller wil timeout after one second)
At this point, your first node will receive a message, such that:
(tcap2@REDACTED)228> flush().
Shell got {'$gen_call',{<7155.38.0>,#Ref<7155.0.0.59>},
{call,erlang,now,[],<7155.31.0>}}
ok
(NOTE 2: <<7155.38.0>> is pid() of the process that issued the call)
(NOTE 3: <<7155.31.0>> is pid() of the group leader)
Thus, you could exploit this in order to write your own logger, which would front rex:
Consider below for incorporation in your code:
...
-export( [init/1, logger/0] ).
...
-record( state, {rex, logger} ).
...
init( _ )
->
...
% ---------------
% Redirecting REX
% ---------------
OldREX = whereis( REX ),
unregister( rex ),
register( rex, self() ),
main_loop( #state{rex=OldREX, logger=spawn(?MODULE, logger, []} )
.
main_loop( S=#state{} )
->
NewS = receive
Request -> fwd_request(Request, S)
end,
main_loop( NewS )
;
main_loop( {shutdown, #state{rex=OldREX, logger=LPID}} )
->
% ---------------
% Exit gracefully
% ---------------
unregister( rex ),
register( rex, OldRex ),
LPID ! shutdown,
exit( normal )
.
fwd_request( Request={'$gen_call',{CallerPID,CallerRef}, {call,Mod,Func,Args,_CallerGroupLeader}}, S=#state{rex=OldRex, logger=LPID} )
->
OldRex ! Request,
LPID ! {log, CallerPid, CallerRef, Mod, Func, Args},
S
;
fwd_request( shutdown, S ) -> {shutdown, S};
fwd_request( _, S ) -> S.
% ------
% LOGGER
% ------
logger()
->
receive
{log, CallerPid, CallerRef, Mod, Func, Args}
->
... Do some logging stuff ...
;
shutdown -> exit( normal );
_ -> void
end,
logger()
.
Kind regards
V/
PS
Just want to state the obvious: I did not compile this code. It could contain bugs, but it illustrates the point.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170427/b22b0234/attachment.htm>
More information about the erlang-questions
mailing list