Permalink
Browse files

Rewrite to use a bitmask to represent active loglevels

Also, adapt the rest of lager to use this bitmask as well.
  • Loading branch information...
1 parent 67bce42 commit f4f3dd38176beccef9ea1336a51219491c918709 @Vagabond Vagabond committed Nov 30, 2012
Showing with 207 additions and 141 deletions.
  1. +10 −10 include/lager.hrl
  2. +43 −22 src/lager.erl
  3. +1 −1 src/lager_app.erl
  4. +10 −10 src/lager_console_backend.erl
  5. +7 −7 src/lager_file_backend.erl
  6. +107 −69 src/lager_util.erl
  7. +29 −22 test/lager_test_backend.erl
View
@@ -20,15 +20,15 @@
-define(LEVELS,
[debug, info, notice, warning, error, critical, alert, emergency, none]).
--define(DEBUG, 7).
--define(INFO, 6).
--define(NOTICE, 5).
--define(WARNING, 4).
--define(ERROR, 3).
--define(CRITICAL, 2).
--define(ALERT, 1).
--define(EMERGENCY, 0).
--define(LOG_NONE, -1).
+-define(DEBUG, 128).
+-define(INFO, 64).
+-define(NOTICE, 32).
+-define(WARNING, 16).
+-define(ERROR, 8).
+-define(CRITICAL, 4).
+-define(ALERT, 2).
+-define(EMERGENCY, 1).
+-define(LOG_NONE, 0).
-define(LEVEL2NUM(Level),
case Level of
@@ -55,7 +55,7 @@
end).
-define(SHOULD_LOG(Level),
- lager_util:level_to_num(Level) =< element(1, lager_mochiglobal:get(loglevel, {?LOG_NONE, []}))).
+ (lager_util:level_to_num(Level) band element(1, lager_mochiglobal:get(loglevel, {?LOG_NONE, []}))) /= 0).
-define(NOTIFY(Level, Pid, Format, Args),
gen_event:notify(lager_event, {log, lager_msg:new(io_lib:format(Format, Args),
View
@@ -24,7 +24,7 @@
%% API
-export([start/0,
log/3, log/4,
- trace_file/2, trace_file/3, trace_console/1, trace_console/2,
+ trace/2, trace/3, trace_file/2, trace_file/3, trace_console/1, trace_console/2,
clear_all_traces/0, stop_trace/1, status/0,
get_loglevel/1, set_loglevel/2, set_loglevel/3, get_loglevels/0,
minimum_loglevel/1, posix_error/1,
@@ -62,21 +62,24 @@ dispatch_log(Severity, Metadata, Format, Args, Size) when is_atom(Severity)->
Pid ->
{LevelThreshold,TraceFilters} = lager_mochiglobal:get(loglevel,{?LOG_NONE,[]}),
SeverityAsInt=lager_util:level_to_num(Severity),
- Destinations = case TraceFilters of
- [] -> [];
- _ ->
- lager_util:check_traces(Metadata,SeverityAsInt,TraceFilters,[])
- end,
- case (LevelThreshold >= SeverityAsInt orelse Destinations =/= []) of
- true ->
+ case (LevelThreshold band SeverityAsInt) /= 0 of
+ true ->
+ Destinations = case TraceFilters of
+ [] ->
+ [];
+ _ ->
+ lager_util:check_traces(Metadata,SeverityAsInt,TraceFilters,[])
+ end,
Timestamp = lager_util:format_time(),
- Msg=case Args of
- A when is_list(A) ->safe_format_chop(Format,Args,Size);
- _ -> Format
+ Msg = case Args of
+ A when is_list(A) ->
+ safe_format_chop(Format,Args,Size);
+ _ ->
+ Format
end,
gen_event:sync_notify(Pid, {log, lager_msg:new(Msg, Timestamp,
Severity, Metadata, Destinations)});
- _ ->
+ _ ->
ok
end
end.
@@ -118,7 +121,8 @@ trace_file(File, Filter, Level) ->
{MinLevel, Traces} = lager_mochiglobal:get(loglevel),
case lists:member(Trace, Traces) of
false ->
- lager_mochiglobal:put(loglevel, {MinLevel, [Trace|Traces]});
+ {_, {mask, TraceMask}, _} = Trace,
+ lager_mochiglobal:put(loglevel, {MinLevel bor TraceMask, [Trace|Traces]});
_ ->
ok
end,
@@ -134,13 +138,20 @@ trace_console(Filter) ->
trace_console(Filter, debug).
trace_console(Filter, Level) ->
- Trace0 = {Filter, Level, lager_console_backend},
+ trace(lager_console_backend, Filter, Level).
+
+trace(Backend, Filter) ->
+ trace(Backend, Filter, debug).
+
+trace(Backend, Filter, Level) ->
+ Trace0 = {Filter, Level, Backend},
case lager_util:validate_trace(Trace0) of
{ok, Trace} ->
{MinLevel, Traces} = lager_mochiglobal:get(loglevel),
case lists:member(Trace, Traces) of
false ->
- lager_mochiglobal:put(loglevel, {MinLevel, [Trace|Traces]});
+ {_, {mask, TraceMask}, _} = Trace,
+ lager_mochiglobal:put(loglevel, {MinLevel bor TraceMask, [Trace|Traces]});
_ -> ok
end,
{ok, Trace};
@@ -149,8 +160,9 @@ trace_console(Filter, Level) ->
end.
stop_trace({_Filter, _Level, Target} = Trace) ->
- {MinLevel, Traces} = lager_mochiglobal:get(loglevel),
+ {_, Traces} = lager_mochiglobal:get(loglevel),
NewTraces = lists:delete(Trace, Traces),
+ MinLevel = minimum_loglevel(get_loglevels() ++ get_trace_levels(NewTraces)),
lager_mochiglobal:put(loglevel, {MinLevel, NewTraces}),
case get_loglevel(Target) of
none ->
@@ -167,7 +179,7 @@ stop_trace({_Filter, _Level, Target} = Trace) ->
ok.
clear_all_traces() ->
- {MinLevel, _Traces} = lager_mochiglobal:get(loglevel),
+ MinLevel = minimum_loglevel(get_loglevels()),
lager_mochiglobal:put(loglevel, {MinLevel, []}),
lists:foreach(fun(Handler) ->
case get_loglevel(Handler) of
@@ -203,8 +215,8 @@ status() ->
set_loglevel(Handler, Level) when is_atom(Level) ->
Reply = gen_event:call(lager_event, Handler, {set_loglevel, Level}, infinity),
%% recalculate min log level
- MinLog = minimum_loglevel(get_loglevels()),
{_, Traces} = lager_mochiglobal:get(loglevel),
+ MinLog = minimum_loglevel(get_loglevels() ++ get_trace_levels(Traces)),
lager_mochiglobal:put(loglevel, {MinLog, Traces}),
Reply.
@@ -214,15 +226,17 @@ set_loglevel(Handler, Ident, Level) when is_atom(Level) ->
io:format("handler: ~p~n", [{Handler, Ident}]),
Reply = gen_event:call(lager_event, {Handler, Ident}, {set_loglevel, Level}, infinity),
%% recalculate min log level
- MinLog = minimum_loglevel(get_loglevels()),
{_, Traces} = lager_mochiglobal:get(loglevel),
+ MinLog = minimum_loglevel(get_loglevels() ++ get_trace_levels(Traces)),
lager_mochiglobal:put(loglevel, {MinLog, Traces}),
Reply.
%% @doc Get the loglevel for a particular backend. In the case that the backend
%% has multiple identifiers, the lowest is returned
get_loglevel(Handler) ->
case gen_event:call(lager_event, Handler, get_loglevel, infinity) of
+ {mask, Mask} ->
+ erlang:hd(lager_util:mask_to_levels(Mask));
X when is_integer(X) ->
lager_util:num_to_level(X);
Y -> Y
@@ -244,10 +258,17 @@ get_loglevels() ->
Handler <- gen_event:which_handlers(lager_event)].
%% @private
-minimum_loglevel([]) ->
- -1; %% lower than any log level, logging off
minimum_loglevel(Levels) ->
- erlang:hd(lists:reverse(lists:sort(Levels))).
+ lists:foldl(fun({mask, Mask}, Acc) ->
+ Mask bor Acc;
+ (Level, Acc) when is_integer(Level) ->
+ lager_util:config_to_mask(lager_util:num_to_level(Level)) bor Acc;
+ (_, Acc) ->
+ Acc
+ end, 0, Levels).
+
+get_trace_levels(Traces) ->
+ lists:map(fun({_, Level, _}) -> Level end, Traces).
%% @doc Print the format string `Fmt' with `Args' safely with a size
%% limit of `Limit'. If the format string is invalid, or not enough
View
@@ -34,7 +34,7 @@ start() ->
start(_StartType, _StartArgs) ->
%% until lager is completely started, allow all messages to go through
- lager_mochiglobal:put(loglevel, {?DEBUG, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(debug)), []}),
{ok, Pid} = lager_sup:start_link(),
Handlers = case application:get_env(lager, handlers) of
undefined ->
@@ -43,7 +43,7 @@ init([Level, true]) -> % for backwards compatibility
init([Level,false]) -> % for backwards compatibility
init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
init([Level,{Formatter,FormatterConfig}]) when is_atom(Level), is_atom(Formatter)->
- try lager_util:config_to_level(Level) of
+ try lager_util:config_to_mask(Level) of
Levels ->
{ok, #state{level=Levels,
formatter=Formatter,
@@ -55,10 +55,10 @@ init([Level,{Formatter,FormatterConfig}]) when is_atom(Level), is_atom(Formatte
%% @private
-handle_call(get_loglevel, #state{level=[Level|_]} = State) ->
- {ok, lager_util:level_to_num(Level), State};
+handle_call(get_loglevel, #state{level=Level} = State) ->
+ {ok, Level, State};
handle_call({set_loglevel, Level}, State) ->
- try lager_util:config_to_level(Level) of
+ try lager_util:config_to_mask(Level) of
Levels ->
{ok, ok, State#state{level=Levels}}
catch
@@ -137,7 +137,7 @@ console_log_test_() ->
unregister(user),
register(user, Pid),
erlang:group_leader(Pid, whereis(lager_event)),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
lager:log(info, self(), "Test message"),
receive
{io_request, From, ReplyAs, {put_chars, unicode, Msg}} ->
@@ -156,7 +156,7 @@ console_log_test_() ->
register(user, Pid),
erlang:group_leader(Pid, whereis(lager_event)),
gen_event:add_handler(lager_event, lager_console_backend, [info, true]),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
lager:info("Test message"),
lager:info("Test message"),
PidStr = pid_to_list(self()),
@@ -176,7 +176,7 @@ console_log_test_() ->
register(user, Pid),
gen_event:add_handler(lager_event, lager_console_backend, info),
erlang:group_leader(Pid, whereis(lager_event)),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
lager:debug("Test message"),
receive
{io_request, From, ReplyAs, {put_chars, unicode, _Msg}} ->
@@ -204,7 +204,7 @@ console_log_test_() ->
unregister(user),
register(user, Pid),
gen_event:add_handler(lager_event, lager_console_backend, info),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
erlang:group_leader(Pid, whereis(lager_event)),
lager:debug("Test message"),
receive
@@ -242,7 +242,7 @@ console_log_test_() ->
unregister(user),
register(user, Pid),
gen_event:add_handler(lager_event, lager_console_backend, info),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
lager:set_loglevel(lager_console_backend, '!=info'),
erlang:group_leader(Pid, whereis(lager_event)),
lager:debug("Test message"),
@@ -272,7 +272,7 @@ console_log_test_() ->
unregister(user),
register(user, Pid),
gen_event:add_handler(lager_event, lager_console_backend, info),
- lager_mochiglobal:put(loglevel, {?INFO, []}),
+ lager_mochiglobal:put(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
lager:set_loglevel(lager_console_backend, '=debug'),
erlang:group_leader(Pid, whereis(lager_event)),
lager:debug("Test message"),
View
@@ -90,8 +90,8 @@ handle_call({set_loglevel, Level}, #state{name=Ident} = State) ->
?INT_LOG(notice, "Changed loglevel of ~s to ~p", [Ident, Level]),
{ok, ok, State#state{level=Levels}}
end;
-handle_call(get_loglevel, #state{level=[Level|_]} = State) ->
- {ok, lager_util:level_to_num(Level), State};
+handle_call(get_loglevel, #state{level=Level} = State) ->
+ {ok, Level, State};
handle_call(_Request, State) ->
{ok, ok, State}.
@@ -207,7 +207,7 @@ validate_logfile(H) ->
false.
validate_loglevel(Level) ->
- try lager_util:config_to_level(Level) of
+ try lager_util:config_to_mask(Level) of
Levels ->
Levels
catch
@@ -226,11 +226,11 @@ schedule_rotation(Name, Date) ->
get_loglevel_test() ->
{ok, Level, _} = handle_call(get_loglevel,
- #state{name="bar", level=lager_util:config_to_level(info), fd=0, inode=0}),
- ?assertEqual(Level, lager_util:level_to_num(info)),
+ #state{name="bar", level=lager_util:config_to_mask(info), fd=0, inode=0}),
+ ?assertEqual(Level, lager_util:config_to_mask(info)),
{ok, Level2, _} = handle_call(get_loglevel,
- #state{name="foo", level=lager_util:config_to_level(warning), fd=0, inode=0}),
- ?assertEqual(Level2, lager_util:level_to_num(warning)).
+ #state{name="foo", level=lager_util:config_to_mask(warning), fd=0, inode=0}),
+ ?assertEqual(Level2, lager_util:config_to_mask(warning)).
rotation_test() ->
{ok, {FD, Inode, _}} = lager_util:open_logfile("test.log", true),
Oops, something went wrong.

0 comments on commit f4f3dd3

Please sign in to comment.