Skip to content

Commit

Permalink
Merge pull request #1878 from ferd/autoreload-logger
Browse files Browse the repository at this point in the history
Reload logger config in shell
  • Loading branch information
ferd authored Sep 10, 2018
2 parents 30daae6 + 0303567 commit 3136cb5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/rebar_prv_shell.erl
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ reread_config(AppsToStart, State) ->
lists:member(App, Running),
lists:member(App, AppsToStart),
not lists:member(App, BlackList)],
_ = rebar_utils:reread_config(ConfigList),
_ = rebar_utils:reread_config(ConfigList, [update_logger]),
ok
end.

Expand Down
53 changes: 51 additions & 2 deletions src/rebar_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
info_useless/2,
list_dir/1,
user_agent/0,
reread_config/1,
reread_config/1, reread_config/2,
get_proxy_auth/0,
is_list_of_strings/1]).

Expand Down Expand Up @@ -436,6 +436,18 @@ user_agent() ->
?FMT("Rebar/~ts (OTP/~ts)", [Vsn, otp_release()]).

reread_config(ConfigList) ->
%% Default to not re-configuring the logger for now;
%% this can leak logs in CT redirection when setting up hooks
%% for example. If we want to turn it on by default, we may
%% want to disable it in CT at the same time or figure out a
%% way to silence it.
%% The same pattern may apply to other tasks, so let's enable
%% case-by-case.
reread_config(ConfigList, []).

reread_config(ConfigList, Opts) ->
UpdateLoggerConfig = erlang:function_exported(logger, module_info, 0) andalso
proplists:get_value(update_logger, Opts, false),
%% NB: we attempt to mimic -config here, which survives app reload,
%% hence {persistent, true}.
SetEnv = case version_tuple(?MODULE:otp_release()) of
Expand All @@ -445,15 +457,52 @@ reread_config(ConfigList) ->
fun (App, Key, Val) -> application:set_env(App, Key, Val, [{persistent, true}]) end
end,
try
Res =
[SetEnv(Application, Key, Val)
|| Config <- ConfigList,
{Application, Items} <- Config,
{Key, Val} <- Items]
{Key, Val} <- Items],
case UpdateLoggerConfig of
true -> reread_logger_config();
false -> ok
end,
Res
catch _:_ ->
?ERROR("The configuration file submitted could not be read "
"and will be ignored.", [])
end.

%% @private since the kernel app is already booted, re-reading its config
%% requires doing some magic to dynamically patch running handlers to
%% deal with the current value.
reread_logger_config() ->
KernelCfg = application:get_all_env(kernel),
LogCfg = proplists:get_value(logger, KernelCfg),
case LogCfg of
undefined ->
ok;
_ ->
%% Extract and apply settings related to primary configuration
%% -- primary config is used for settings shared across handlers
LogLvlPrimary = proplists:get_value(logger_info, KernelCfg, all),
{FilterDefault, Filters} =
case lists:keyfind(filters, 1, KernelCfg) of
false -> {log, []};
{filters, FoundDef, FoundFilter} -> {FoundDef, FoundFilter}
end,
Primary = #{level => LogLvlPrimary,
filter_default => FilterDefault,
filters => Filters},
%% Load the correct handlers based on their individual config.
[case Id of
default -> logger:update_handler_config(Id, Cfg);
_ -> logger:add_handler(Id, Mod, Cfg)
end || {handler, Id, Mod, Cfg} <- LogCfg],
logger:set_primary_config(Primary),
ok
end.


%% @doc Given env. variable `FOO' we want to expand all references to
%% it in `InStr'. References can have two forms: `$FOO' and `${FOO}'
%% The end of form `$FOO' is delimited with whitespace or EOL
Expand Down

0 comments on commit 3136cb5

Please sign in to comment.