Sfoglia il codice sorgente

Disable I/O to the console if the old-style Erlang console is used

There's a nasty problem with the Erlang VM + lager when the old-style
Erlang console is used.  You can use the "-oldshell" flag to explicitly
get the old-style shell.  However, if the Erlang VM is started when
*not* associated with a pseudo-tty, the VM will silently use the
old-style shell (because the new-style shell requires a pty to
support command line editing, etc.).  The most common way of starting
the Erlang VM without a pty is to start it via a non-interactive
SSH session.

This patch is opinionated in what to do in the case when the old-
style shell is detected.  My opinion is:

1. Shout loudly to the console log (in a separate Erlang process, so
   that the main lager event handler proc won't be blocked by any
   problems with the old-style console).  It's almost certainly
   likely that you really don't want to run Erlang with the old-style
   shell.  But many sysadmins don't look closely at their systems'
   log files, so (for example) shouting the same message 10x in a row
   is legit.  Reviewers: YMMV.
2. Set a SASL alarm.  Again, many sysadmins' are bad at looking at
   log messages.  Setting a SASL alarm is another method to try to
   get their attention.

To test, create a test script called `/tmp/testit.sh`, changing the
`-pz` parameter to point to the correct place for lager's `ebin`
subdirectory:

    #!/bin/sh

    erl -pz /Users/fritchie/b/src/lager/ebin -eval '{application:start(sasl), lager_console_backend:init([error, true]), timer:sleep(5*1000), io:format("\n\nInfo: ~p\n\n", [{{alarms, alarm_handler:get_alarms()}, {user_drv, whereis(user_drv)}}]), erlang:halt()}.'

Then run it twice, using the following:

    First time: ssh -t localhost sh /tmp/testit.sh
    Second time: ssh localhost sh /tmp/testit.sh

The last lines of the first time should look like:

    Info: {{alarms,[]},{user_drv,<0.22.0>}}

The last lines of the second time should look like:

    Info: {{alarms,
               [{lager_console_backend,
                    "WARNING: old-style console is in use, so lager_console_backend log output to the console is disabled.  Restart the VM on a pseudo-tty to ensure use of the new-style VM console."}]},
           {user_drv,undefined}}
pull/139/head
Scott Lystig Fritchie 12 anni fa
committed by Andrew Thompson
parent
commit
1ea378af9c
1 ha cambiato i file con 41 aggiunte e 2 eliminazioni
  1. +41
    -2
      src/lager_console_backend.erl

+ 41
- 2
src/lager_console_backend.erl Vedi File

@ -40,6 +40,13 @@ init([Level, true]) -> % for backwards compatibility
init([Level,false]) -> % for backwards compatibility
init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]);
init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
IsSafe = case is_new_style_console_available() of
false=Res ->
spawn(fun warn_user/0),
Res;
Res ->
Res
end,
Colors = case application:get_env(lager, colored) of
{ok, true} ->
{ok, LagerColors} = application:get_env(lager, colors),
@ -47,8 +54,10 @@ init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
_ -> []
end,
try lager_util:config_to_mask(Level) of
Levels ->
try {IsSafe, lager_util:config_to_mask(Level)} of
{false, _} ->
{error, "Old style console was detected"};
{true, Levels} ->
{ok, #state{level=Levels,
formatter=Formatter,
format_config=FormatterConfig,
@ -108,6 +117,36 @@ eol() ->
"\r\n"
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.
warn_user() ->
Msg = lists:flatten(
io_lib:format("WARNING: old-style console is in use, so ~s "
"log output to the console is disabled. "
"Restart the VM on a pseudo-tty to ensure "
"use of the new-style VM console.",
[?MODULE])),
catch alarm_handler:set_alarm({?MODULE, Msg}),
[begin
error_logger:warning_msg(Msg),
timer:sleep(1000)
end || _ <- lists:seq(1, 10)].
-ifdef(TEST).
console_log_test_() ->
%% tiny recursive fun that pretends to be a group leader

Caricamento…
Annulla
Salva