|
|
@@ -22,6 +22,8 @@
|
|
|
-include("emqx_cm.hrl").
|
|
|
-include("logger.hrl").
|
|
|
-include("types.hrl").
|
|
|
+-include("emqx_mqtt.hrl").
|
|
|
+-include("emqx_external_trace.hrl").
|
|
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
|
|
-include_lib("stdlib/include/qlc.hrl").
|
|
|
-include_lib("stdlib/include/ms_transform.hrl").
|
|
|
@@ -457,6 +459,14 @@ discard_session(ClientId) when is_binary(ClientId) ->
|
|
|
when
|
|
|
Action :: kick | discard | {takeover, 'begin'} | {takeover, 'end'} | takeover_kick.
|
|
|
request_stepdown(Action, ConnMod, Pid) ->
|
|
|
+ ?EXT_TRACE_WITH_PROCESS_FUN(
|
|
|
+ broker_disconnect,
|
|
|
+ [],
|
|
|
+ maps:merge(basic_trace_attrs(Pid), action_to_reason(Action)),
|
|
|
+ fun([]) -> do_request_stepdown(Action, ConnMod, Pid) end
|
|
|
+ ).
|
|
|
+
|
|
|
+do_request_stepdown(Action, ConnMod, Pid) ->
|
|
|
Timeout =
|
|
|
case Action == kick orelse Action == discard of
|
|
|
true -> ?T_KICK;
|
|
|
@@ -696,7 +706,9 @@ lookup_channels(local, ClientId) ->
|
|
|
[ChanPid || {_, ChanPid} <- ets:lookup(?CHAN_TAB, ClientId)].
|
|
|
|
|
|
-spec lookup_client(
|
|
|
- {clientid, emqx_types:clientid()} | {username, emqx_types:username()} | {chan_pid, chan_pid()}
|
|
|
+ {clientid, emqx_types:clientid()}
|
|
|
+ | {username, emqx_types:username()}
|
|
|
+ | {chan_pid, chan_pid()}
|
|
|
) ->
|
|
|
[channel_info()].
|
|
|
lookup_client({username, Username}) ->
|
|
|
@@ -842,3 +854,56 @@ kick_session_chans(ClientId, ChanPids) ->
|
|
|
ok
|
|
|
end,
|
|
|
lists:foreach(fun(Pid) -> kick_session(ClientId, Pid) end, ChanPids).
|
|
|
+
|
|
|
+-if(?EMQX_RELEASE_EDITION == ee).
|
|
|
+
|
|
|
+basic_trace_attrs(Pid) ->
|
|
|
+ %% io:format("lookup_client({chan_pid, Pid}): ~p", [lookup_client({chan_pid, Pid})]),
|
|
|
+ case lookup_client({chan_pid, Pid}) of
|
|
|
+ [] ->
|
|
|
+ #{'channel.pid' => iolist_to_binary(io_lib:format("~p", [Pid]))};
|
|
|
+ [{_Chan, #{clientinfo := ClientInfo, conninfo := ConnInfo}, _Stats}] ->
|
|
|
+ #{
|
|
|
+ 'client.clientid' => maps:get(clientid, ClientInfo, undefined),
|
|
|
+ 'client.username' => maps:get(username, ClientInfo, undefined),
|
|
|
+ 'client.proto_name' => maps:get(proto_name, ConnInfo, undefined),
|
|
|
+ 'client.proto_ver' => maps:get(proto_ver, ConnInfo, undefined),
|
|
|
+ 'client.is_bridge' => maps:get(is_bridge, ClientInfo, undefined),
|
|
|
+ 'client.sockname' => ntoa(maps:get(sockname, ConnInfo, undefined)),
|
|
|
+ 'client.peername' => ntoa(maps:get(peername, ConnInfo, undefined))
|
|
|
+ };
|
|
|
+ _ ->
|
|
|
+ #{}
|
|
|
+ end.
|
|
|
+
|
|
|
+action_to_reason(Action) when
|
|
|
+ Action =:= kick orelse
|
|
|
+ Action =:= takeover_kick
|
|
|
+->
|
|
|
+ #{
|
|
|
+ 'client.disconnect.reason_code' => ?RC_ADMINISTRATIVE_ACTION,
|
|
|
+ 'client.disconnect.reason' => kick
|
|
|
+ };
|
|
|
+action_to_reason(discard) ->
|
|
|
+ #{
|
|
|
+ 'client.disconnect.reason_code' => ?RC_SESSION_TAKEN_OVER,
|
|
|
+ 'client.disconnect.reason' => discard
|
|
|
+ };
|
|
|
+action_to_reason({takeover, 'begin'}) ->
|
|
|
+ #{
|
|
|
+ 'client.disconnect.reason_code' => ?RC_SESSION_TAKEN_OVER,
|
|
|
+ 'client.disconnect.reason' => takeover_begin
|
|
|
+ };
|
|
|
+action_to_reason({takeover, 'end'}) ->
|
|
|
+ #{
|
|
|
+ 'client.disconnect.reason_code' => ?RC_SESSION_TAKEN_OVER,
|
|
|
+ 'disconnect.reason' => takeover_end
|
|
|
+ }.
|
|
|
+
|
|
|
+ntoa(undefined) ->
|
|
|
+ undefined;
|
|
|
+ntoa(IpPort) ->
|
|
|
+ emqx_utils:ntoa(IpPort).
|
|
|
+
|
|
|
+-else.
|
|
|
+-endif.
|