Add CLI for log tracer (#1973)

This commit is contained in:
Shawn 2018-11-23 11:01:10 +08:00 committed by turtleDeng
parent 551d5d99d2
commit 2bd0f16884
1 changed files with 15 additions and 24 deletions

View File

@ -20,12 +20,12 @@
-export([start_link/0]). -export([start_link/0]).
-export([trace/2]). -export([trace/2]).
-export([start_trace/2, lookup_traces/0, stop_trace/1]). -export([start_trace/3, lookup_traces/0, stop_trace/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]). code_change/3]).
-record(state, {level, org_top_level, traces}). -record(state, {traces}).
-type(trace_who() :: {client_id | topic, binary()}). -type(trace_who() :: {client_id | topic, binary()}).
@ -37,7 +37,9 @@
[{peername, [{peername,
[client_id,"@",peername," "], [client_id,"@",peername," "],
[client_id, " "]}], [client_id, " "]}],
[]}, [{peername,
[peername," "],
[]}]},
msg,"\n"]}}). msg,"\n"]}}).
-spec(start_link() -> {ok, pid()} | ignore | {error, term()}). -spec(start_link() -> {ok, pid()} | ignore | {error, term()}).
@ -56,11 +58,11 @@ trace(publish, #message{from = From, topic = Topic, payload = Payload})
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
%% @doc Start to trace client_id or topic. %% @doc Start to trace client_id or topic.
-spec(start_trace(trace_who(), string()) -> ok | {error, term()}). -spec(start_trace(trace_who(), logger:level(), string()) -> ok | {error, term()}).
start_trace({client_id, ClientId}, LogFile) -> start_trace({client_id, ClientId}, Level, LogFile) ->
start_trace({start_trace, {client_id, ClientId}, LogFile}); start_trace({start_trace, {client_id, ClientId}, Level, LogFile});
start_trace({topic, Topic}, LogFile) -> start_trace({topic, Topic}, Level, LogFile) ->
start_trace({start_trace, {topic, Topic}, LogFile}). start_trace({start_trace, {topic, Topic}, Level, LogFile}).
start_trace(Req) -> gen_server:call(?MODULE, Req, infinity). start_trace(Req) -> gen_server:call(?MODULE, Req, infinity).
@ -81,29 +83,26 @@ lookup_traces() ->
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
init([]) -> init([]) ->
{ok, #state{level = emqx_config:get_env(trace_level, debug), {ok, #state{traces = #{}}}.
org_top_level = get_top_level(),
traces = #{}}}.
handle_call({start_trace, Who, LogFile}, _From, State = #state{level = Level, traces = Traces}) -> handle_call({start_trace, Who, Level, LogFile}, _From, State = #state{traces = Traces}) ->
case logger:add_handler(handler_id(Who), logger_disk_log_h, case logger:add_handler(handler_id(Who), logger_disk_log_h,
#{level => Level, #{level => Level,
formatter => ?FORMAT, formatter => ?FORMAT,
filesync_repeat_interval => 1000, filesync_repeat_interval => no_repeat,
config => #{type => halt, file => LogFile}, config => #{type => halt, file => LogFile},
filter_default => stop, filter_default => stop,
filters => [{meta_key_filter, filters => [{meta_key_filter,
{fun filter_by_meta_key/2, Who} }]}) of {fun filter_by_meta_key/2, Who} }]}) of
ok -> ok ->
set_top_level(all), % open the top logger level to 'all'
emqx_logger:info("[Tracer] start trace for ~p", [Who]), emqx_logger:info("[Tracer] start trace for ~p", [Who]),
{reply, ok, State#state{traces = maps:put(Who, LogFile, Traces)}}; {reply, ok, State#state{traces = maps:put(Who, {Level, LogFile}, Traces)}};
{error, Reason} -> {error, Reason} ->
emqx_logger:error("[Tracer] start trace for ~p failed, error: ~p", [Who, Reason]), emqx_logger:error("[Tracer] start trace for ~p failed, error: ~p", [Who, Reason]),
{reply, {error, Reason}, State} {reply, {error, Reason}, State}
end; end;
handle_call({stop_trace, Who}, _From, State = #state{org_top_level = OrgTopLevel, traces = Traces}) -> handle_call({stop_trace, Who}, _From, State = #state{traces = Traces}) ->
case maps:find(Who, Traces) of case maps:find(Who, Traces) of
{ok, _LogFile} -> {ok, _LogFile} ->
case logger:remove_handler(handler_id(Who)) of case logger:remove_handler(handler_id(Who)) of
@ -112,7 +111,6 @@ handle_call({stop_trace, Who}, _From, State = #state{org_top_level = OrgTopLevel
{error, Reason} -> {error, Reason} ->
emqx_logger:error("[Tracer] stop trace for ~p failed, error: ~p", [Who, Reason]) emqx_logger:error("[Tracer] stop trace for ~p failed, error: ~p", [Who, Reason])
end, end,
set_top_level(OrgTopLevel), % reset the top logger level to original value
{reply, ok, State#state{traces = maps:remove(Who, Traces)}}; {reply, ok, State#state{traces = maps:remove(Who, Traces)}};
error -> error ->
{reply, {error, not_found}, State} {reply, {error, not_found}, State}
@ -144,13 +142,6 @@ handler_id({topic, Topic}) ->
handler_id({client_id, ClientId}) -> handler_id({client_id, ClientId}) ->
list_to_atom("clientid_" ++ binary_to_list(ClientId)). list_to_atom("clientid_" ++ binary_to_list(ClientId)).
get_top_level() ->
#{level := OrgTopLevel} = logger:get_primary_config(),
OrgTopLevel.
set_top_level(Level) ->
logger:set_primary_config(level, Level).
filter_by_meta_key(#{meta:=Meta}=LogEvent, {MetaKey, MetaValue}) -> filter_by_meta_key(#{meta:=Meta}=LogEvent, {MetaKey, MetaValue}) ->
case maps:find(MetaKey, Meta) of case maps:find(MetaKey, Meta) of
{ok, MetaValue} -> LogEvent; {ok, MetaValue} -> LogEvent;