Pārlūkot izejas kodu

Starting down the path of making backends handle multiple sinks (primary use case is tracing)

pull/264/head
John R. Daily pirms 10 gadiem
vecāks
revīzija
6f6b0110f2
5 mainītis faili ar 65 papildinājumiem un 23 dzēšanām
  1. +23
    -14
      src/lager.erl
  2. +12
    -3
      src/lager_app.erl
  3. +16
    -3
      src/lager_config.erl
  4. +1
    -1
      src/lager_file_backend.erl
  5. +13
    -2
      src/lager_handler_watcher.erl

+ 23
- 14
src/lager.erl Parādīt failu

@ -21,6 +21,7 @@
-include("lager.hrl").
-define(LAGER_MD_KEY, '__lager_metadata').
-define(TRACE_SINK, '__trace_sink').
%% API
-export([start/0,
@ -173,16 +174,24 @@ trace_file(File, Filter, Level, Options) ->
Trace0 = {Filter, Level, {lager_file_backend, File}},
case lager_util:validate_trace(Trace0) of
{ok, Trace} ->
Handlers = gen_event:which_handlers(lager_event),
Handlers = lager_config:global_get(handlers, []),
%% check if this file backend is already installed
Res = case lists:member({lager_file_backend, File}, Handlers) of
false ->
%% install the handler
LogFileConfig = lists:keystore(level, 1, lists:keystore(file, 1, Options, {file, File}), {level, none}),
supervisor:start_child(lager_handler_watcher_sup,
[lager_event, {lager_file_backend, File}, LogFileConfig]);
_ ->
{ok, exists}
Res = case lists:keyfind({lager_file_backend, File}, 2, Handlers) of
false ->
%% install the handler
LogFileConfig =
lists:keystore(level, 1,
lists:keystore(file, 1,
Options,
{file, File}),
{level, none}),
HandlerInfo =
lager_app:start_handler(?TRACE_SINK, lager_file_backend,
LogFileConfig),
lager_config:global_set(handlers, [HandlerInfo|Handlers]);
{Watcher, _Handler} ->
lager_handler_watcher:add_sink(Watcher, ?TRACE_SINK),
{ok, exists}
end,
case Res of
{ok, _} ->
@ -250,17 +259,17 @@ stop_trace_int({Backend, _Filter, _Level} = Trace) ->
ok.
clear_all_traces() ->
{Level, _Traces} = lager_config:get(loglevel),
Handlers = lager_config:global_get(handlers, []),
_ = lager_util:trace_filter(none),
lager_config:set(loglevel, {Level, []}),
lists:foreach(fun(Handler) ->
lists:foreach(fun({Watcher, Handler}) ->
case get_loglevel(Handler) of
none ->
gen_event:delete_handler(lager_event, Handler, []);
gen_event:delete_handler(?TRACE_SINK, Handler, []),
langer_handler_watcher:remove_sink(Watcher, ?TRACE_SINK)
_ ->
ok
end
end, gen_event:which_handlers(lager_event)).
end, Handlers).
status() ->
Handlers = gen_event:which_handlers(lager_event),

+ 12
- 3
src/lager_app.erl Parādīt failu

@ -27,6 +27,7 @@
-endif.
-export([start/0,
start/2,
start_handler/3,
stop/1]).
-define(?THROTTLE, lager_backend_throttle).
@ -75,11 +76,19 @@ start_handlers(_Sink, {ok, Handlers}) when not is_list(Handlers) ->
throw({error, bad_config});
start_handlers(Sink, {ok, Handlers}) ->
%% handlers failing to start are handled in the handler_watcher
_ = [supervisor:start_child(lager_handler_watcher_sup,
[Sink, Module, Config]) ||
{Module, Config} <- expand_handlers(Handlers)],
lager_config:global_set(handlers,
lists:map(fun({Module, Config}) ->
start_handler(Sink, Module, Config)
end,
expand_handlers(Handlers))),
ok.
start_handler(Sink, Module, Config) ->
{ok, Watcher} = supervisor:start_child(lager_handler_watcher_sup,
[Sink, Module, Config]),
BackendId = Module:config_to_id(Config),
{BackendId, Watcher}.
interpret_hwm(undefined) ->
undefined;
interpret_hwm({ok, undefined}) ->

+ 16
- 3
src/lager_config.erl Parādīt failu

@ -20,12 +20,14 @@
-include("lager.hrl").
-export([new/0, get/1, get/2, get/3, set/2, set/3]).
-export([new/0, get/1, get/2, get/3, set/2, set/3,
global_get/1, global_get/2, global_set/2]).
-define(TBL, lager_config).
-define(GLOBAL, '_global').
%% For multiple sinks, the key is now the registered event name and the old key
%% as a tuple.
%% as a tuple.
%%
%% {{lager_event, loglevel}, Value} instead of {loglevel, Value}
@ -41,9 +43,20 @@ new() ->
%% use insert_new here so that if we're in an appup we don't mess anything up
%%
%% until lager is completely started, allow all messages to go through
ets:insert_new(?TBL, {{lager_event, loglevel}, {element(2, lager_util:config_to_mask(debug)), []}}),
ets:insert_new(?TBL, {{lager_event, loglevel}, {element(2, lager_util:config_to_mask(debug))}}),
%% Need to be able to find the `lager_handler_watcher' for all handlers
ets:insert_new(?TBL, {{?GLOBAL, handlers}, []}),
ok.
global_get(Key) ->
global_get(Key, undefined).
global_get(Key, Default) ->
get(?GLOBAL, Key, Default).
global_set(Key, Value) ->
set(?GLOBAL, Key, Value).
get(Key) ->
get(?DEFAULT_SINK, Key, undefined).

+ 1
- 1
src/lager_file_backend.erl Parādīt failu

@ -164,7 +164,7 @@ terminate(_Reason, #state{fd=FD}) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% @private convert the config into a gen_event handler ID
%% Convert the config into a gen_event handler ID
config_to_id({Name,_Severity}) when is_list(Name) ->
{?MODULE, Name};
config_to_id({Name,_Severity,_Size,_Rotation,_Count}) ->

+ 13
- 2
src/lager_handler_watcher.erl Parādīt failu

@ -33,12 +33,12 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
-export([start_link/3, start/3]).
-export([start_link/3, start/3, add_sink/2, remove_sink/2]).
-record(state, {
module :: atom(),
config :: any(),
sink :: pid() | atom()
sinks :: list(pid() | atom())
}).
start_link(Sink, Module, Config) ->
@ -47,13 +47,24 @@ start_link(Sink, Module, Config) ->
start(Sink, Module, Config) ->
gen_server:start(?MODULE, [Sink, Module, Config], []).
remove_sink(Pid, Sink) ->
gen_server:call(Pid, {remove_sink, Sink}).
add_sink(Pid, Sink) ->
gen_server:call(Pid, {add_sink, Sink}).
init([Sink, Module, Config]) ->
install_handler(Sink, Module, Config),
{ok, #state{sink=Sink, module=Module, config=Config}}.
handle_call({remove_sink, Sink}, _From, #state{sinks=Sinks}=State) ->
{reply, ok, State#{sinks=lists:delete(Sink, Sinks)}};
handle_call({add_sink, Sink}, _From, #state{sinks=Sinks}=State) ->
{reply, ok, State#{sinks=[Sink|Sinks]}};
handle_call(_Call, _From, State) ->
{reply, ok, State}.
handle_cast(_Request, State) ->
{noreply, State}.

Notiek ielāde…
Atcelt
Saglabāt