Browse Source

Overhaul start up and add killer config

Previously, configuration would come from application:get_env/3 or
proplists:get_value/3. Now we standardize on a single format
for retrieving values from the environment or from a proplist.
pull/346/head
Mark Allen 9 years ago
parent
commit
4b5260c452
1 changed files with 49 additions and 57 deletions
  1. +49
    -57
      src/lager_app.erl

+ 49
- 57
src/lager_app.erl View File

@ -29,7 +29,7 @@
start/2,
start_handler/3,
stop/1,
boot/0]).
boot/1]).
-define(FILENAMES, '__lager_file_backend_filenames').
-define(THROTTLE, lager_backend_throttle).
@ -53,21 +53,19 @@ start_throttle(Sink, Threshold, Window) ->
[Sink, ?THROTTLE, [Threshold, Window]]),
ok.
determine_async_behavior(_Sink, {ok, undefined}, _Window) ->
ok;
determine_async_behavior(_Sink, undefined, _Window) ->
ok;
determine_async_behavior(_Sink, {ok, Threshold}, _Window) when not is_integer(Threshold) orelse Threshold < 0 ->
determine_async_behavior(_Sink, Threshold, _Window) when not is_integer(Threshold) orelse Threshold < 0 ->
error_logger:error_msg("Invalid value for 'async_threshold': ~p~n",
[Threshold]),
throw({error, bad_config});
determine_async_behavior(Sink, {ok, Threshold}, undefined) ->
determine_async_behavior(Sink, Threshold, undefined) ->
start_throttle(Sink, Threshold, erlang:trunc(Threshold * 0.2));
determine_async_behavior(_Sink, {ok, Threshold}, {ok, Window}) when not is_integer(Window) orelse Window > Threshold orelse Window < 0 ->
determine_async_behavior(_Sink, Threshold, Window) when not is_integer(Window) orelse Window > Threshold orelse Window < 0 ->
error_logger:error_msg(
"Invalid value for 'async_threshold_window': ~p~n", [Window]),
throw({error, bad_config});
determine_async_behavior(Sink, {ok, Threshold}, {ok, Window}) ->
determine_async_behavior(Sink, Threshold, Window) ->
start_throttle(Sink, Threshold, Window).
start_handlers(_Sink, undefined) ->
@ -119,14 +117,22 @@ clean_up_config_checks() ->
interpret_hwm(undefined) ->
undefined;
interpret_hwm({ok, undefined}) ->
undefined;
interpret_hwm({ok, HWM}) when not is_integer(HWM) orelse HWM < 0 ->
interpret_hwm(HWM) when not is_integer(HWM) orelse HWM < 0 ->
_ = lager:log(warning, self(), "Invalid error_logger high water mark: ~p, disabling", [HWM]),
undefined;
interpret_hwm({ok, HWM}) ->
interpret_hwm(HWM) ->
HWM.
maybe_install_sink_killer(_Sink, undefined, _ReinstallTimer) -> ok;
maybe_install_sink_killer(Sink, HWM, undefined) -> maybe_install_sink_killer(Sink, HWM, 5000);
maybe_install_sink_killer(Sink, HWM, ReinstallTimer) when is_integer(HWM) andalso is_integer(ReinstallTimer)
andalso HWM >= 0 andalso ReinstallTimer >= 0 ->
_ = supervisor:start_child(lager_handler_watcher_sup, [Sink, lager_manager_killer,
[HWM, ReinstallTimer]]);
maybe_install_sink_killer(_Sink, HWM, ReinstallTimer) ->
error_logger:error_msg("Invalid value for 'killer_hwm': ~p or 'killer_reinstall_after': ~p", [HWM, ReinstallTimer]),
throw({error, bad_config}).
start_error_logger_handler({ok, false}, _HWM, _Whitelist) ->
[];
start_error_logger_handler(_, HWM, undefined) ->
@ -147,24 +153,6 @@ start_error_logger_handler(_, HWM, {ok, WhiteList}) ->
throw({error, bad_config})
end,
%% Conditionally start the high watermark killer.
case application:get_env(lager, killer_hwm) of
undefined -> ok;
{ok, undefined} -> ok;
{ok, KillerHWM} when is_integer(KillerHWM), KillerHWM >= 0 ->
KillerReinstallAfter = case application:get_env(lager, killer_reinstall_after) of
undefined -> 5000;
{ok, undefined} -> 5000;
{ok, V} when is_integer(V), V >= 0 -> V;
{ok, BadKillerReinstallAfter} ->
error_logger:error_msg("Invalid value for 'cooldown': ~p~n",
[BadKillerReinstallAfter]),
throw({error, bad_config})
end,
_ = supervisor:start_child(lager_handler_watcher_sup,
[?DEFAULT_SINK, lager_manager_killer,
[KillerHWM, KillerReinstallAfter]])
end,
case supervisor:start_child(lager_handler_watcher_sup, [error_logger, error_logger_lager_h, [HWM, GlStrategy]]) of
{ok, _} ->
@ -174,17 +162,6 @@ start_error_logger_handler(_, HWM, {ok, WhiteList}) ->
[]
end.
%% `determine_async_behavior/3' is called with the results from either
%% `application:get_env/2' and `proplists:get_value/2'. Since
%% `application:get_env/2' wraps a successful retrieval in an `{ok,
%% Value}' tuple, do the same for the result from
%% `proplists:get_value/2'.
wrap_proplist_value(undefined) ->
undefined;
wrap_proplist_value(Value) ->
{ok, Value}.
configure_sink(Sink, SinkDef) ->
lager_config:new_sink(Sink),
ChildId = lager_util:make_internal_sink_name(Sink),
@ -193,12 +170,11 @@ configure_sink(Sink, SinkDef) ->
{gen_event, start_link,
[{local, Sink}]},
permanent, 5000, worker, dynamic}),
determine_async_behavior(Sink,
wrap_proplist_value(
proplists:get_value(async_threshold, SinkDef)),
wrap_proplist_value(
proplists:get_value(async_threshold_window, SinkDef))
determine_async_behavior(Sink, proplists:get_value(async_threshold, SinkDef),
proplists:get_value(async_threshold_window, SinkDef)
),
maybe_install_sink_killer(Sink, proplists:get_value(killer_hwm, SinkDef),
proplists:get_value(killer_reinstall_after, SinkDef)),
start_handlers(Sink,
proplists:get_value(handlers, SinkDef, [])),
@ -209,6 +185,8 @@ configure_extra_sinks(Sinks) ->
lists:foreach(fun({Sink, Proplist}) -> configure_sink(Sink, Proplist) end,
Sinks).
get_env(Application, Key) ->
get_env(Application, Key, undefined).
%% R15 doesn't know about application:get_env/3
get_env(Application, Key, Default) ->
get_env_default(application:get_env(Application, Key),
@ -222,35 +200,49 @@ get_env_default({ok, Value}, _Default) ->
start(_StartType, _StartArgs) ->
{ok, Pid} = lager_sup:start_link(),
SavedHandlers = boot(),
_ = boot('__all_extra'),
_ = boot('__traces'),
clean_up_config_checks(),
{ok, Pid, SavedHandlers}.
boot() ->
%% Handle the default sink.
determine_async_behavior(?DEFAULT_SINK,
application:get_env(lager, async_threshold),
application:get_env(lager, async_threshold_window)),
get_env(lager, async_threshold),
get_env(lager, async_threshold_window)),
maybe_install_sink_killer(?DEFAULT_SINK, get_env(lager, killer_hwm),
get_env(lager, killer_reinstall_after)),
start_handlers(?DEFAULT_SINK,
get_env(lager, handlers, ?DEFAULT_HANDLER_CONF)),
lager:update_loglevel_config(?DEFAULT_SINK),
SavedHandlers = start_error_logger_handler(
application:get_env(lager, error_logger_redirect),
interpret_hwm(application:get_env(lager, error_logger_hwm)),
application:get_env(lager, error_logger_whitelist)
get_env(lager, error_logger_redirect),
interpret_hwm(get_env(lager, error_logger_hwm)),
get_env(lager, error_logger_whitelist)
),
_ = lager_util:trace_filter(none),
SavedHandlers.
%% Now handle extra sinks
configure_extra_sinks(get_env(lager, extra_sinks, [])),
boot('__traces') ->
_ = lager_util:trace_filter(none),
ok = add_configured_traces();
ok = add_configured_traces(),
boot('__all_extra') ->
configure_extra_sinks(get_env(lager, extra_sinks, []));
clean_up_config_checks(),
boot(?DEFAULT_SINK) -> boot();
boot(Sink) ->
AllSinksDef = get_env(lager, extra_sinks, []),
boot_sink(Sink, lists:keyfind(Sink, 1, AllSinksDef)).
SavedHandlers.
boot_sink(Sink, {Sink, Def}) ->
configure_sink(Sink, Def);
boot_sink(Sink, false) ->
configure_sink(Sink, []).
stop(Handlers) ->
lists:foreach(fun(Handler) ->

Loading…
Cancel
Save