aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2018-11-30 17:45:18 +0100
committerSiri Hansen <[email protected]>2018-11-30 17:45:18 +0100
commitc64420ee0c50958c61958fcec4947fbbe721a661 (patch)
tree6b774c053cd4d45021a4b21406867604191a0d4b
parent892409dd4a517f2a6d75db13384c468519df899f (diff)
downloadotp-c64420ee0c50958c61958fcec4947fbbe721a661.tar.gz
otp-c64420ee0c50958c61958fcec4947fbbe721a661.tar.bz2
otp-c64420ee0c50958c61958fcec4947fbbe721a661.zip
[logger] Re-create log file if deleted
This is an update to logger_std_h, which makes it play well with tools like logrotate.
-rw-r--r--lib/kernel/src/logger_std_h.erl45
-rw-r--r--lib/kernel/test/logger_std_h_SUITE.erl23
2 files changed, 51 insertions, 17 deletions
diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl
index ebe741e331..63d1dbaba2 100644
--- a/lib/kernel/src/logger_std_h.erl
+++ b/lib/kernel/src/logger_std_h.erl
@@ -328,27 +328,30 @@ file_ctrl_loop(Fd, DevName, Synced,
receive
%% asynchronous event
{log,Bin} ->
- Result = write_to_dev(Fd, Bin, DevName, PrevWriteResult, HandlerName),
- file_ctrl_loop(Fd, DevName, false,
+ Fd1 = ensure(Fd, DevName),
+ Result = write_to_dev(Fd1, Bin, DevName, PrevWriteResult, HandlerName),
+ file_ctrl_loop(Fd1, DevName, false,
Result, PrevSyncResult, HandlerName);
%% synchronous event
{{log,Bin},{From,MRef}} ->
- check_exist(Fd, DevName),
- Result = write_to_dev(Fd, Bin, DevName, PrevWriteResult, HandlerName),
+ Fd1 = ensure(Fd, DevName),
+ Result = write_to_dev(Fd1, Bin, DevName, PrevWriteResult, HandlerName),
From ! {MRef,ok},
- file_ctrl_loop(Fd, DevName, false,
+ file_ctrl_loop(Fd1, DevName, false,
Result, PrevSyncResult, HandlerName);
filesync ->
- Result = sync_dev(Fd, DevName, Synced, PrevSyncResult, HandlerName),
- file_ctrl_loop(Fd, DevName, true,
+ Fd1 = ensure(Fd, DevName),
+ Result = sync_dev(Fd1, DevName, Synced, PrevSyncResult, HandlerName),
+ file_ctrl_loop(Fd1, DevName, true,
PrevWriteResult, Result, HandlerName);
{filesync,{From,MRef}} ->
- Result = sync_dev(Fd, DevName, Synced, PrevSyncResult, HandlerName),
+ Fd1 = ensure(Fd, DevName),
+ Result = sync_dev(Fd1, DevName, Synced, PrevSyncResult, HandlerName),
From ! {MRef,ok},
- file_ctrl_loop(Fd, DevName, true,
+ file_ctrl_loop(Fd1, DevName, true,
PrevWriteResult, Result, HandlerName);
stop ->
@@ -356,11 +359,25 @@ file_ctrl_loop(Fd, DevName, Synced,
stopped
end.
-check_exist(DevName, DevName) when is_atom(DevName) ->
- ok;
-check_exist(_Fd, FileName) ->
- _ = spawn_link(fun() -> {ok,_} = file:read_file_info(FileName) end),
- ok.
+%% In order to play well with tools like logrotate, we need to be able
+%% to re-create the file if it has disappeared (e.g. if rotated by
+%% logrotate)
+ensure(Fd,DevName) when is_atom(DevName) ->
+ Fd;
+ensure(Fd,FileName) ->
+ case file:read_file_info(FileName) of
+ {ok,_} ->
+ Fd;
+ _ ->
+ _ = file:close(Fd),
+ _ = file:close(Fd), % delayed_write cause close not to close
+ case do_open_log_file({file,FileName}) of
+ {ok,Fd1} ->
+ Fd1;
+ Error ->
+ exit({could_not_reopen_file,Error})
+ end
+ end.
write_to_dev(DevName, Bin, _DevName, _PrevWriteResult, _HandlerName)
when is_atom(DevName) ->
diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl
index a1159f280c..eb17a6d857 100644
--- a/lib/kernel/test/logger_std_h_SUITE.erl
+++ b/lib/kernel/test/logger_std_h_SUITE.erl
@@ -136,7 +136,8 @@ all() ->
mem_kill_new,
mem_kill_std,
restart_after,
- handler_requests_under_load
+ handler_requests_under_load,
+ recreate_deleted_log
].
add_remove_instance_tty(_Config) ->
@@ -1255,6 +1256,22 @@ handler_requests_under_load(Config) ->
handler_requests_under_load(cleanup, _Config) ->
ok = stop_handler(?MODULE).
+recreate_deleted_log(Config) ->
+ {Log,_HConfig,_StdHConfig} =
+ start_handler(?MODULE, ?FUNCTION_NAME, Config),
+ logger:notice("first",?domain),
+ logger_std_h:filesync(?MODULE),
+ ok = file:rename(Log,Log++".old"),
+ logger:notice("second",?domain),
+ logger_std_h:filesync(?MODULE),
+ {ok,<<"first\n">>} = file:read_file(Log++".old"),
+ {ok,<<"second\n">>} = file:read_file(Log),
+ ok.
+recreate_deleted_log(cleanup, _Config) ->
+ ok = stop_handler(?MODULE).
+
+%%%-----------------------------------------------------------------
+%%%
send_requests(HName, TO, Reqs = [{Req,Res}|Rs]) ->
receive
{From,finish} ->
@@ -1276,8 +1293,8 @@ send_requests(HName, TO, Reqs = [{Req,Res}|Rs]) ->
%%%-----------------------------------------------------------------
%%%
-start_handler(Name, TTY, Config) when TTY == standard_io;
- TTY == standard_error->
+start_handler(Name, TTY, _Config) when TTY == standard_io;
+ TTY == standard_error->
ok = logger:add_handler(Name,
logger_std_h,
#{config => #{type => TTY},