Cli command support --format=json output
This commit is contained in:
parent
06d291e354
commit
d5ccb9f92f
3
Makefile
3
Makefile
|
@ -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
|
||||||
|
|
|
@ -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>"]},
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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]).
|
Loading…
Reference in New Issue