Merge pull request #139 from basho/adt-avoid-console-io-hang
Disable console backend if oldshell is used
diff --git a/include/lager.hrl b/include/lager.hrl
index ac84d98..ade93e1 100644
--- a/include/lager.hrl
+++ b/include/lager.hrl
@@ -84,7 +84,7 @@
%% from a gen_event handler
spawn(fun() ->
case catch(gen_event:which_handlers(lager_event)) of
- X when X == []; X == {'EXIT', noproc} ->
+ X when X == []; X == {'EXIT', noproc}; X == [lager_backend_throttle] ->
%% there's no handlers yet or lager isn't running, try again
%% in half a second.
timer:sleep(500),
diff --git a/src/lager_console_backend.erl b/src/lager_console_backend.erl
index 8f968e0..c64fe9c 100644
--- a/src/lager_console_backend.erl
+++ b/src/lager_console_backend.erl
@@ -47,15 +47,27 @@
_ -> []
end,
- try lager_util:config_to_mask(Level) of
- Levels ->
+ try {is_new_style_console_available(), lager_util:config_to_mask(Level)} of
+ {false, _} ->
+ Msg = "Lager's console backend is incompatible with the 'old' shell, not enabling it",
+ %% be as noisy as possible, log to every possible place
+ try
+ alarm_handler:set_alarm({?MODULE, "WARNING: " ++ Msg})
+ catch
+ _:_ ->
+ error_logger:warning_msg(Msg ++ "~n")
+ end,
+ io:format("WARNING: " ++ Msg ++ "~n"),
+ ?INT_LOG(warning, Msg, []),
+ {error, {fatal, old_shell}};
+ {true, Levels} ->
{ok, #state{level=Levels,
formatter=Formatter,
format_config=FormatterConfig,
colors=Colors}}
catch
_:_ ->
- {error, bad_log_level}
+ {error, {fatal, bad_log_level}}
end;
init(Level) ->
init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]).
@@ -109,6 +121,23 @@
end.
-ifdef(TEST).
+is_new_style_console_available() ->
+ true.
+-else.
+is_new_style_console_available() ->
+ %% Criteria:
+ %% 1. If the user has specified '-noshell' on the command line,
+ %% then we will pretend that the new-style console is available.
+ %% If there is no shell at all, then we don't have to worry
+ %% about log events being blocked by the old-style shell.
+ %% 2. If the user_drv process iss registered, all is OK.
+ %% 'user_drv' is a registered proc name used by the "new"
+ %% console driver.
+ init:get_argument(noshell) /= error orelse
+ is_pid(whereis(user_drv)).
+-endif.
+
+-ifdef(TEST).
console_log_test_() ->
%% tiny recursive fun that pretends to be a group leader
F = fun(Self) ->
diff --git a/src/lager_file_backend.erl b/src/lager_file_backend.erl
index b8a3411..6e1d2ef 100644
--- a/src/lager_file_backend.erl
+++ b/src/lager_file_backend.erl
@@ -99,7 +99,7 @@
case validate_logfile_proplist(LogFileConfig) of
false ->
%% falied to validate config
- {error, bad_config};
+ {error, {fatal, bad_config}};
Config ->
%% probabably a better way to do this, but whatever
[Name, Level, Date, Size, Count, SyncInterval, SyncSize, SyncOn, CheckInterval, Formatter, FormatterConfig] =
diff --git a/src/lager_handler_watcher.erl b/src/lager_handler_watcher.erl
index 2086346..ac34119 100644
--- a/src/lager_handler_watcher.erl
+++ b/src/lager_handler_watcher.erl
@@ -23,6 +23,8 @@
-behaviour(gen_server).
+-include("lager.hrl").
+
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
@@ -73,6 +75,8 @@
handle_info(reinstall_handler, #state{module=Module, config=Config, event=Event} = State) ->
install_handler(Event, Module, Config),
{noreply, State};
+handle_info(stop, State) ->
+ {stop, normal, State};
handle_info(_Info, State) ->
{noreply, State}.
@@ -87,12 +91,18 @@
install_handler(Event, Module, Config) ->
case gen_event:add_sup_handler(Event, Module, Config) of
ok ->
- _ = lager:log(debug, self(), "Lager installed handler ~p into ~p", [Module, Event]),
+ ?INT_LOG(debug, "Lager installed handler ~p into ~p", [Module, Event]),
lager:update_loglevel_config(),
ok;
+ {error, {fatal, Reason}} ->
+ ?INT_LOG(error, "Lager fatally failed to install handler ~p into"
+ " ~p, NOT retrying: ~p", [Module, Event, Reason]),
+ %% tell ourselves to stop
+ self() ! stop,
+ ok;
Error ->
%% try to reinstall it later
- _ = lager:log(error, self(), "Lager failed to install handler ~p into"
+ ?INT_LOG(error, "Lager failed to install handler ~p into"
" ~p, retrying later : ~p", [Module, Event, Error]),
erlang:send_after(5000, self(), reinstall_handler),
ok
@@ -145,10 +155,10 @@
?assert(lists:member(lager_crash_backend, gen_event:which_handlers(lager_event))),
timer:sleep(6000),
?assertEqual(2, lager_test_backend:count()),
- {_Level, _Time, Message, _Metadata} = lager_test_backend:pop(),
- ?assertEqual("Lager event handler lager_crash_backend exited with reason crash", lists:flatten(Message)),
- {_Level2, _Time2, Message2, _Metadata} = lager_test_backend:pop(),
- ?assertMatch("Lager failed to install handler lager_crash_backend into lager_event, retrying later :"++_, lists:flatten(Message2)),
+ {_Severity, _Date, Msg, _Metadata} = lager_test_backend:pop(),
+ ?assertEqual("Lager event handler lager_crash_backend exited with reason crash", lists:flatten(Msg)),
+ {_Severity2, _Date2, Msg2, _Metadata2} = lager_test_backend:pop(),
+ ?assertMatch("Lager failed to install handler lager_crash_backend into lager_event, retrying later :"++_, lists:flatten(Msg2)),
?assertEqual(false, lists:member(lager_crash_backend, gen_event:which_handlers(lager_event)))
after
application:stop(lager),
diff --git a/src/lager_handler_watcher_sup.erl b/src/lager_handler_watcher_sup.erl
index b3161ae..f3763aa 100644
--- a/src/lager_handler_watcher_sup.erl
+++ b/src/lager_handler_watcher_sup.erl
@@ -35,5 +35,5 @@
{ok, {{simple_one_for_one, 10, 60},
[
{lager_handler_watcher, {lager_handler_watcher, start_link, []},
- transient, 5000, worker, [lager_handler_watcher]}
+ temporary, 5000, worker, [lager_handler_watcher]}
]}}.