fix issue #449 - Improve the CLI of cluster

This commit is contained in:
Feng 2016-02-11 15:54:35 +08:00
parent 44d598fd87
commit 767c4ccc6e
1 changed files with 52 additions and 49 deletions

View File

@ -14,8 +14,6 @@
%% limitations under the License. %% limitations under the License.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @doc emqttd cli
%% @author Feng Lee <feng@emqtt.io>
-module(emqttd_cli). -module(emqttd_cli).
-include("emqttd.hrl"). -include("emqttd.hrl").
@ -106,56 +104,47 @@ broker(_) ->
{"broker metrics", "query broker metrics"}]). {"broker metrics", "query broker metrics"}]).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @doc Cluster with other node %% @doc Cluster with other nodes
cluster([]) -> cluster(["join", SNode]) ->
Nodes = emqttd_broker:running_nodes(), case emqttd_cluster:join(emqttd_node:parse_name(SNode)) of
?PRINT("cluster nodes: ~p~n", [Nodes]); ok ->
?PRINT_MSG("Join the cluster successfully.~n"),
cluster(usage) -> cluster(["status"]);
?PRINT_CMD("cluster [<Node>]", "cluster with node, query cluster info"); {error, Error} ->
?PRINT("Failed to join the cluster: ~p~n", [Error])
cluster([SNode]) ->
Node = emqttd_dist:parse_node(SNode),
case lists:member(Node, emqttd_broker:running_nodes()) of
true ->
?PRINT("~s is already clustered~n", [Node]);
false ->
cluster(Node, fun() ->
emqttd_plugins:unload(),
stop_apps(),
emqttd_mnesia:cluster(Node),
start_apps()
end)
end; end;
cluster(["leave"]) ->
case emqttd_cluster:leave() of
ok ->
?PRINT_MSG("Leave the cluster successfully.~n"),
cluster(["status"]);
{error, Error} ->
?PRINT("Failed to leave the cluster: ~p~n", [Error])
end;
cluster(["remove", SNode]) ->
case emqttd_cluster:remove(emqttd_node:parse_name(SNode)) of
ok ->
?PRINT_MSG("Remove the node from cluster successfully.~n"),
cluster(["status"]);
{error, Error} ->
?PRINT("Failed to remove the node from cluster: ~p~n", [Error])
end;
cluster(["status"]) ->
?PRINT("Cluster status: ~p~n", [emqttd_cluster:status()]);
cluster(_) -> cluster(_) ->
cluster(usage). ?USAGE([{"cluster join <Node>", "Join the cluster"},
{"cluster leave", "Leave the cluster"},
cluster(Node, DoCluster) -> {"cluster remove <Node>","Remove the node from cluster"},
cluster(net_adm:ping(Node), Node, DoCluster). {"cluster status", "Cluster status"}]).
cluster(pong, Node, DoCluster) ->
case emqttd:is_running(Node) of
true ->
DoCluster(),
?PRINT("cluster with ~s successfully.~n", [Node]);
false ->
?PRINT("emqttd is not running on ~s~n", [Node])
end;
cluster(pang, Node, _DoCluster) ->
?PRINT("Cannot connect to ~s~n", [Node]).
stop_apps() ->
[application:stop(App) || App <- [emqttd, esockd, gproc]].
start_apps() ->
[application:start(App) || App <- [gproc, esockd, emqttd]].
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% @doc Query clients %% @doc Query clients
clients(["list"]) -> clients(["list"]) ->
emqttd_mnesia:dump(ets, mqtt_client, fun print/1); dump(ets, mqtt_client, fun print/1);
clients(["show", ClientId]) -> clients(["show", ClientId]) ->
if_client(ClientId, fun print/1); if_client(ClientId, fun print/1);
@ -180,10 +169,10 @@ sessions(["list"]) ->
[sessions(["list", Type]) || Type <- ["persistent", "transient"]]; [sessions(["list", Type]) || Type <- ["persistent", "transient"]];
sessions(["list", "persistent"]) -> sessions(["list", "persistent"]) ->
emqttd_mnesia:dump(ets, mqtt_persistent_session, fun print/1); dump(ets, mqtt_persistent_session, fun print/1);
sessions(["list", "transient"]) -> sessions(["list", "transient"]) ->
emqttd_mnesia:dump(ets, mqtt_transient_session, fun print/1); dump(ets, mqtt_transient_session, fun print/1);
sessions(["show", ClientId]) -> sessions(["show", ClientId]) ->
MP = {{bin(ClientId), '_'}, '_'}, MP = {{bin(ClientId), '_'}, '_'},
@ -463,7 +452,7 @@ print(#mqtt_client{client_id = ClientId, clean_sess = CleanSess,
?PRINT("Client(~s, clean_sess=~s, username=~s, peername=~s, connected_at=~p)~n", ?PRINT("Client(~s, clean_sess=~s, username=~s, peername=~s, connected_at=~p)~n",
[ClientId, CleanSess, Username, [ClientId, CleanSess, Username,
emqttd_net:format(Peername), emqttd_net:format(Peername),
emqttd_util:now_to_secs(ConnectedAt)]); emqttd_time:now_to_secs(ConnectedAt)]);
print(#mqtt_topic{topic = Topic, node = Node}) -> print(#mqtt_topic{topic = Topic, node = Node}) ->
?PRINT("~s on ~s~n", [Topic, Node]); ?PRINT("~s on ~s~n", [Topic, Node]);
@ -493,7 +482,7 @@ print(subscription, ClientId, Subscriptions) ->
?PRINT("~s: ~p~n", [ClientId, TopicTable]). ?PRINT("~s: ~p~n", [ClientId, TopicTable]).
format(created_at, Val) -> format(created_at, Val) ->
emqttd_util:now_to_secs(Val); emqttd_time:now_to_secs(Val);
format(subscriptions, List) -> format(subscriptions, List) ->
string:join([io_lib:format("~s:~w", [Topic, Qos]) || {Topic, Qos} <- List], ","); string:join([io_lib:format("~s:~w", [Topic, Qos]) || {Topic, Qos} <- List], ",");
@ -503,3 +492,17 @@ format(_, Val) ->
bin(S) -> iolist_to_binary(S). bin(S) -> iolist_to_binary(S).
%%TODO: ...
dump(ets, Table, Fun) ->
dump(ets, Table, ets:first(Table), Fun).
dump(ets, _Table, '$end_of_table', _Fun) ->
ok;
dump(ets, Table, Key, Fun) ->
case ets:lookup(Table, Key) of
[Record] -> Fun(Record);
[] -> ignore
end,
dump(ets, Table, ets:next(Table, Key), Fun).