Cli command support --format=json output

This commit is contained in:
turtled 2017-05-17 16:27:18 +08:00
parent 06d291e354
commit d5ccb9f92f
4 changed files with 77 additions and 30 deletions

View File

@ -2,7 +2,7 @@ PROJECT = emqttd
PROJECT_DESCRIPTION = Erlang MQTT Broker PROJECT_DESCRIPTION = Erlang MQTT Broker
PROJECT_VERSION = 2.2 PROJECT_VERSION = 2.2
DEPS = goldrush gproc lager esockd mochiweb pbkdf2 lager_syslog bcrypt clique DEPS = goldrush gproc lager esockd mochiweb pbkdf2 lager_syslog bcrypt clique jsx
dep_goldrush = git https://github.com/basho/goldrush 0.1.9 dep_goldrush = git https://github.com/basho/goldrush 0.1.9
dep_gproc = git https://github.com/uwiger/gproc dep_gproc = git https://github.com/uwiger/gproc
@ -14,6 +14,7 @@ dep_pbkdf2 = git https://github.com/emqtt/pbkdf2 2.0.1
dep_lager_syslog = git https://github.com/basho/lager_syslog dep_lager_syslog = git https://github.com/basho/lager_syslog
dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master dep_bcrypt = git https://github.com/smarkets/erlang-bcrypt master
dep_clique = git https://github.com/turtleDeng/clique dep_clique = git https://github.com/turtleDeng/clique
dep_jsx = git https://github.com/talentdeficit/jsx
ERLC_OPTS += +'{parse_transform, lager_transform}' ERLC_OPTS += +'{parse_transform, lager_transform}'
NO_AUTOPATCH = cuttlefish NO_AUTOPATCH = cuttlefish

View File

@ -4,7 +4,7 @@
{modules,[]}, {modules,[]},
{registered,[emqttd_sup]}, {registered,[emqttd_sup]},
{applications,[kernel,stdlib,gproc,lager,esockd,mochiweb, {applications,[kernel,stdlib,gproc,lager,esockd,mochiweb,
lager_syslog,pbkdf2,bcrypt]}, lager_syslog,pbkdf2,bcrypt,jsx]},
{env,[]}, {env,[]},
{mod,{emqttd_app,[]}}, {mod,{emqttd_app,[]}},
{maintainers,["Feng Lee <feng@emqtt.io>"]}, {maintainers,["Feng Lee <feng@emqtt.io>"]},

View File

@ -27,9 +27,32 @@
register_cli() -> register_cli() ->
F = fun() -> emqttd_mnesia:running_nodes() end, F = fun() -> emqttd_mnesia:running_nodes() end,
clique:register_node_finder(F), clique:register_node_finder(F),
clique:register_writer("json", emqttd_cli_format),
register_usage(), register_usage(),
register_cmd(). register_cmd().
run([]) ->
AllUsage = [["broker"],
["cluster"],
["acl"],
["clients"],
["sessions"],
["routes"],
["topics"],
["subscriptions"],
["plugins"],
["bridges"],
["vm"],
["trace"],
["status"],
["listeners"],
["mnesia"]],
io:format("--------------------------------------------------------------------------------~n"),
lists:foreach(fun(Item) ->
io:format("~ts", [clique_usage:find(Item)]),
io:format("--------------------------------------------------------------------------------~n")
end, AllUsage);
run(Cmd) -> run(Cmd) ->
clique:run(Cmd). clique:run(Cmd).
@ -127,11 +150,10 @@ broker_stats() ->
Cmd = ["broker", "stats"], Cmd = ["broker", "stats"],
Callback = Callback =
fun (_, _, _) -> fun (_, _, _) ->
Table = lists:map( lists:map(
fun({Key, Val}) -> fun({Key, Val}) ->
io_lib:format("~-20s: ~w~n", [Key, Val]) clique_status:list(Key, io_lib:format("~p", [Val]))
end, emqttd_stats:getstats()), end, emqttd_stats:getstats())
[clique_status:list(Table)]
end, end,
clique:register_command(Cmd, [], [], Callback). clique:register_command(Cmd, [], [], Callback).
@ -139,11 +161,10 @@ broker_metrics() ->
Cmd = ["broker", "metrics"], Cmd = ["broker", "metrics"],
Callback = Callback =
fun (_, _, _) -> fun (_, _, _) ->
Table = lists:map( lists:map(
fun({Key, Val}) -> fun({Key, Val}) ->
io_lib:format("~-24s: ~w~n", [Key, Val]) clique_status:list(Key, io_lib:format("~p", [Val]))
end, lists:sort(emqttd_metrics:all())), end, lists:sort(emqttd_metrics:all()))
[clique_status:list(Table)]
end, end,
clique:register_command(Cmd, [], [], Callback). clique:register_command(Cmd, [], [], Callback).
@ -447,11 +468,14 @@ subscriptions_unsubscribe() ->
ClientId = get_value('client_id', Params), ClientId = get_value('client_id', Params),
QoS = get_value('qos', Params), QoS = get_value('qos', Params),
Text = case {Topic, ClientId, QoS} of Text = case {Topic, ClientId, QoS} of
{undefined, _} -> {undefined, _, _} ->
io_lib:format("Invalid topic is undefined~n", []); io_lib:format("Invalid topic is undefined~n", []);
{_, undefined} -> {_, undefined, _} ->
io_lib:format("Invalid client_id is undefined~n", []); io_lib:format("Invalid client_id is undefined~n", []);
{_, _} -> {_, _, undefined} ->
io_lib:format("Invalid qos is undefined~n", []);
{_, _, _} ->
emqttd:unsubscribe(Topic, ClientId), emqttd:unsubscribe(Topic, ClientId),
io_lib:format("Client_id: ~p unsubscribe topic: ~p successfully~n", [ClientId, Topic]) io_lib:format("Client_id: ~p unsubscribe topic: ~p successfully~n", [ClientId, Topic])
end, end,
@ -576,27 +600,22 @@ vm_all() ->
Cmd = ["vm","info"], Cmd = ["vm","info"],
Callback = Callback =
fun (_, _, _) -> fun (_, _, _) ->
Cpu = [vm_info("cpu", K, list_to_float(V)) || {K, V} <- emqttd_vm:loads()],
Load = [io_lib:format("cpu/~-20s: ~s~n", [L, V]) || {L, V} <- emqttd_vm:loads()], Memory = [vm_info("memory", K, V) || {K, V} <- erlang:memory()],
Process = [vm_info("process", K, erlang:system_info(V)) || {K, V} <- [{limit, process_limit}, {count, process_count}]],
Memory = [io_lib:format("memory/~-17s: ~w~n", [Cat, Val]) || {Cat, Val} <- erlang:memory()],
Process = lists:map(fun({Name, Key}) ->
io_lib:format("process/~-16s: ~w~n", [Name, erlang:system_info(Key)])
end, [{limit, process_limit}, {count, process_count}]),
IoInfo = erlang:system_info(check_io), IoInfo = erlang:system_info(check_io),
IO = lists:map(fun(Key) -> Io = [vm_info("io", K, get_value(K, IoInfo)) || K <- [max_fds, active_fds]],
io_lib:format("io/~-21s: ~w~n", [Key, get_value(Key, IoInfo)]) Ports = [vm_info("ports", K, erlang:system_info(V)) || {K, V} <- [{count, port_count}, {limit, port_limit}]],
end, [max_fds, active_fds]), lists:flatten([Cpu, Memory, Process, Io, Ports])
Ports = lists:map(fun({Name, Key}) ->
io_lib:format("ports/~-18s: ~w~n", [Name, erlang:system_info(Key)])
end, [{count, port_count}, {limit, port_limit}]),
[clique_status:text([Load, Memory, Process, IO, Ports])]
end, end,
clique:register_command(Cmd, [], [], Callback). clique:register_command(Cmd, [], [], Callback).
vm_info(Item, K, V) ->
clique_status:list(format_key(Item, K), io_lib:format("~p", [V])).
format_key(Item, K) ->
list_to_atom(lists:concat([Item, "/", K])).
vm_load() -> vm_load() ->
Cmd = ["vm","load"], Cmd = ["vm","load"],
Callback = Callback =

27
src/emqttd_cli_format.erl Normal file
View File

@ -0,0 +1,27 @@
-module (emqttd_cli_format).
-behavior(clique_writer).
%% API
-export([write/1]).
write([{text, Text}]) ->
Json = jsx:encode([{text, lists:flatten(Text)}]),
{io_lib:format("~p~n", [Json]), []};
write([{table, Table}]) ->
Json = jsx:encode(Table),
{io_lib:format("~p~n", [Json]), []};
write([{list, Key, [Value]}| Tail]) ->
Table = lists:reverse(write(Tail, [{Key, Value}])),
Json = jsx:encode(Table),
{io_lib:format("~p~n", [Json]), []};
write(_) ->
{io_lib:format("error~n", []), []}.
write([], Acc) ->
Acc;
write([{list, Key, [Value]}| Tail], Acc) ->
write(Tail, [{Key, Value}| Acc]).