Explorar el Código

Stop leaving test files in the current directory. Just. Stop. It.

Uses lager_util:create_test_dir/0 and lager_util:delete_test_dir/1 to give tests, or groups thereof, their own clean directory to work in.
Turn off whitespace diffs to review, as much code is shifted left to allow sane wrapping within around 100 columns.
pull/384/head
Ted Burghart hace 8 años
padre
commit
6fac9ebc69
Se han modificado 3 ficheros con 782 adiciones y 599 borrados
  1. +111
    -94
      src/lager_crash_log.erl
  2. +573
    -450
      src/lager_file_backend.erl
  3. +98
    -55
      test/lager_rotate.erl

+ 111
- 94
src/lager_crash_log.erl Ver fichero

@ -1,4 +1,6 @@
%% Copyright (c) 2011-2012 Basho Technologies, Inc. All Rights Reserved.
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2011-2017 Basho Technologies, Inc.
%% %%
%% This file is provided to you under the Apache License, %% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file %% Version 2.0 (the "License"); you may not use this file
@ -13,6 +15,8 @@
%% KIND, either express or implied. See the License for the %% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations %% specific language governing permissions and limitations
%% under the License. %% under the License.
%%
%% -------------------------------------------------------------------
%% @doc Lager crash log writer. This module implements a gen_server which writes %% @doc Lager crash log writer. This module implements a gen_server which writes
%% error_logger error messages out to a file in their original format. The %% error_logger error messages out to a file in their original format. The
@ -236,105 +240,118 @@ do_log({log, Event}, #state{name=Name, fd=FD, inode=Inode, flap=Flap,
filesystem_test_() -> filesystem_test_() ->
{foreach, {foreach,
fun() -> fun() ->
file:write_file("crash_test.log", ""),
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers, [{lager_test_backend, info}]),
application:set_env(lager, error_logger_redirect, true),
application:unset_env(lager, crash_log),
lager:start(),
timer:sleep(100),
lager_test_backend:flush()
end,
fun(_) ->
case whereis(lager_crash_log) of
P when is_pid(P) ->
exit(P, kill);
_ -> ok
end,
file:delete("crash_test.log"),
application:stop(lager),
application:stop(goldrush),
error_logger:tty(true)
CrashLog = filename:join(lager_util:create_test_dir(), "crash_test.log"),
file:write_file(CrashLog, []),
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers, [{lager_test_backend, info}]),
application:set_env(lager, error_logger_redirect, true),
application:unset_env(lager, crash_log),
lager:start(),
timer:sleep(100),
lager_test_backend:flush(),
CrashLog
end, end,
[
fun(CrashLog) ->
case whereis(lager_crash_log) of
P when is_pid(P) ->
exit(P, kill);
_ ->
ok
end,
application:stop(lager),
application:stop(goldrush),
lager_util:delete_test_dir(filename:dirname(CrashLog)),
error_logger:tty(true)
end, [
fun(CrashLog) ->
{"under normal circumstances, file should be opened", {"under normal circumstances, file should be opened",
fun() ->
{ok, _} = ?MODULE:start_link("crash_test.log", 65535, 0, undefined, 0),
_ = gen_event:which_handlers(error_logger),
sync_error_logger:error_msg("Test message\n"),
{ok, Bin} = file:read_file("crash_test.log"),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}]))
end
},
fun() ->
{ok, _} = ?MODULE:start_link(CrashLog, 65535, 0, undefined, 0),
_ = gen_event:which_handlers(error_logger),
sync_error_logger:error_msg("Test message\n"),
{ok, Bin} = file:read_file(CrashLog),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}]))
end}
end,
fun(CrashLog) ->
{"file can't be opened on startup triggers an error message", {"file can't be opened on startup triggers an error message",
fun() ->
{ok, FInfo} = file:read_file_info("crash_test.log"),
file:write_file_info("crash_test.log", FInfo#file_info{mode = 0}),
{ok, _} = ?MODULE:start_link("crash_test.log", 65535, 0, undefined, 0),
?assertEqual(1, lager_test_backend:count()),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual("Failed to open crash log file crash_test.log with error: permission denied", lists:flatten(Message))
end
},
fun() ->
{ok, FInfo} = file:read_file_info(CrashLog),
file:write_file_info(CrashLog, FInfo#file_info{mode = 0}),
{ok, _} = ?MODULE:start_link(CrashLog, 65535, 0, undefined, 0),
?assertEqual(1, lager_test_backend:count()),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual(
"Failed to open crash log file " ++ CrashLog ++ " with error: permission denied",
lists:flatten(Message))
end}
end,
fun(CrashLog) ->
{"file that becomes unavailable at runtime should trigger an error message", {"file that becomes unavailable at runtime should trigger an error message",
fun() ->
{ok, _} = ?MODULE:start_link("crash_test.log", 65535, 0, undefined, 0),
?assertEqual(0, lager_test_backend:count()),
sync_error_logger:error_msg("Test message\n"),
_ = gen_event:which_handlers(error_logger),
?assertEqual(1, lager_test_backend:count()),
file:delete("crash_test.log"),
file:write_file("crash_test.log", ""),
{ok, FInfo} = file:read_file_info("crash_test.log"),
file:write_file_info("crash_test.log", FInfo#file_info{mode = 0}),
sync_error_logger:error_msg("Test message\n"),
_ = gen_event:which_handlers(error_logger),
?assertEqual(3, lager_test_backend:count()),
lager_test_backend:pop(),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual("Failed to reopen crash log crash_test.log with error: permission denied", lists:flatten(Message))
end
},
fun() ->
{ok, _} = ?MODULE:start_link(CrashLog, 65535, 0, undefined, 0),
?assertEqual(0, lager_test_backend:count()),
sync_error_logger:error_msg("Test message\n"),
_ = gen_event:which_handlers(error_logger),
?assertEqual(1, lager_test_backend:count()),
file:delete(CrashLog),
file:write_file(CrashLog, ""),
{ok, FInfo} = file:read_file_info(CrashLog),
file:write_file_info(CrashLog, FInfo#file_info{mode = 0}),
sync_error_logger:error_msg("Test message\n"),
_ = gen_event:which_handlers(error_logger),
?assertEqual(3, lager_test_backend:count()),
lager_test_backend:pop(),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual(
"Failed to reopen crash log " ++ CrashLog ++ " with error: permission denied",
lists:flatten(Message))
end}
end,
fun(CrashLog) ->
{"unavailable files that are fixed at runtime should start having log messages written", {"unavailable files that are fixed at runtime should start having log messages written",
fun() ->
{ok, FInfo} = file:read_file_info("crash_test.log"),
OldPerms = FInfo#file_info.mode,
file:write_file_info("crash_test.log", FInfo#file_info{mode = 0}),
{ok, _} = ?MODULE:start_link("crash_test.log", 65535, 0, undefined, 0),
?assertEqual(1, lager_test_backend:count()),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual("Failed to open crash log file crash_test.log with error: permission denied", lists:flatten(Message)),
file:write_file_info("crash_test.log", FInfo#file_info{mode = OldPerms}),
sync_error_logger:error_msg("Test message~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin} = file:read_file("crash_test.log"),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}]))
end
},
fun() ->
{ok, FInfo} = file:read_file_info(CrashLog),
OldPerms = FInfo#file_info.mode,
file:write_file_info(CrashLog, FInfo#file_info{mode = 0}),
{ok, _} = ?MODULE:start_link(CrashLog, 65535, 0, undefined, 0),
?assertEqual(1, lager_test_backend:count()),
{_Level, _Time, Message,_Metadata} = lager_test_backend:pop(),
?assertEqual(
"Failed to open crash log file " ++ CrashLog ++ " with error: permission denied",
lists:flatten(Message)),
file:write_file_info(CrashLog, FInfo#file_info{mode = OldPerms}),
sync_error_logger:error_msg("Test message~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin} = file:read_file(CrashLog),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}]))
end}
end,
fun(CrashLog) ->
{"external logfile rotation/deletion should be handled", {"external logfile rotation/deletion should be handled",
fun() ->
{ok, _} = ?MODULE:start_link("crash_test.log", 65535, 0, undefined, 0),
?assertEqual(0, lager_test_backend:count()),
sync_error_logger:error_msg("Test message~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin} = file:read_file("crash_test.log"),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}])),
file:delete("crash_test.log"),
file:write_file("crash_test.log", ""),
sync_error_logger:error_msg("Test message1~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin1} = file:read_file("crash_test.log"),
?assertMatch([_, "Test message1\n"], re:split(Bin1, "\n", [{return, list}, {parts, 2}])),
file:rename("crash_test.log", "crash_test.log.0"),
sync_error_logger:error_msg("Test message2~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin2} = file:read_file("crash_test.log"),
?assertMatch([_, "Test message2\n"], re:split(Bin2, "\n", [{return, list}, {parts, 2}]))
end
}
]
}.
fun() ->
{ok, _} = ?MODULE:start_link(CrashLog, 65535, 0, undefined, 0),
?assertEqual(0, lager_test_backend:count()),
sync_error_logger:error_msg("Test message~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin} = file:read_file(CrashLog),
?assertMatch([_, "Test message\n"], re:split(Bin, "\n", [{return, list}, {parts, 2}])),
file:delete(CrashLog),
file:write_file(CrashLog, ""),
sync_error_logger:error_msg("Test message1~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin1} = file:read_file(CrashLog),
?assertMatch([_, "Test message1\n"], re:split(Bin1, "\n", [{return, list}, {parts, 2}])),
file:rename(CrashLog, CrashLog ++ ".0"),
sync_error_logger:error_msg("Test message2~n"),
_ = gen_event:which_handlers(error_logger),
{ok, Bin2} = file:read_file(CrashLog),
?assertMatch([_, "Test message2\n"], re:split(Bin2, "\n", [{return, list}, {parts, 2}]))
end}
end
]}.
-endif. -endif.

+ 573
- 450
src/lager_file_backend.erl
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 98
- 55
test/lager_rotate.erl Ver fichero

@ -1,3 +1,23 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2016-2017 Basho Technologies, Inc.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
-module(lager_rotate). -module(lager_rotate).
-compile(export_all). -compile(export_all).
@ -6,54 +26,71 @@
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-endif. -endif.
-record(state, {
dir :: string(),
log1 :: string(),
log1r :: string(),
log2 :: string(),
log2r :: string(),
sink :: string(),
sinkr :: string()
}).
rotate_test_() -> rotate_test_() ->
{foreach, {foreach,
fun() -> fun() ->
file:write_file("test1.log", ""),
file:write_file("test2.log", ""),
file:write_file("test3.log", ""),
file:delete("test1.log.0"),
file:delete("test2.log.0"),
file:delete("test3.log.0"),
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers,
[{lager_file_backend, [{file, "test1.log"}, {level, info}]},
{lager_file_backend, [{file, "test2.log"}, {level, info}]}]),
application:set_env(lager, extra_sinks,
[{sink_event,
[{handlers,
[{lager_file_backend, [{file, "test3.log"}, {level, info}]}]}
]}]),
application:set_env(lager, error_logger_redirect, false),
application:set_env(lager, async_threshold, undefined),
lager:start()
end,
fun(_) ->
file:delete("test1.log"),
file:delete("test2.log"),
file:delete("test3.log"),
file:delete("test1.log.0"),
file:delete("test2.log.0"),
file:delete("test3.log.0"),
application:stop(lager),
application:stop(goldrush),
error_logger:tty(true)
Dir = lager_util:create_test_dir(),
Log1 = filename:join(Dir, "test1.log"),
Log2 = filename:join(Dir, "test2.log"),
Sink = filename:join(Dir, "sink.log"),
State = #state{
dir = Dir,
log1 = Log1,
log1r = Log1 ++ ".0",
log2 = Log2,
log2r = Log2 ++ ".0",
sink = Sink,
sinkr = Sink ++ ".0"
},
file:write_file(Log1, []),
file:write_file(Log2, []),
file:write_file(Sink, []),
error_logger:tty(false),
application:load(lager),
application:set_env(lager, handlers, [
{lager_file_backend, [{file, Log1}, {level, info}]},
{lager_file_backend, [{file, Log2}, {level, info}]} ]),
application:set_env(lager, extra_sinks, [
{sink_event,
[{handlers,
[{lager_file_backend, [{file, Sink}, {level, info}]}]}
]}]),
application:set_env(lager, error_logger_redirect, false),
application:set_env(lager, async_threshold, undefined),
lager:start(),
State
end, end,
[{"Rotate single file",
fun(#state{dir = Dir}) ->
application:stop(lager),
application:stop(goldrush),
lager_util:delete_test_dir(Dir),
error_logger:tty(true)
end, [
fun(State) ->
{"Rotate single file",
fun() -> fun() ->
lager:log(error, self(), "Test message 1"), lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []), lager:log(sink_event, error, self(), "Sink test message 1", []),
lager:rotate_handler({lager_file_backend, "test1.log"}),
ok = wait_until(fun() -> filelib:is_regular("test1.log.0") end, 10),
lager:rotate_handler({lager_file_backend, State#state.log1}),
ok = wait_until(fun() -> filelib:is_regular(State#state.log1r) end, 10),
lager:log(error, self(), "Test message 2"), lager:log(error, self(), "Test message 2"),
lager:log(sink_event, error, self(), "Sink test message 2", []), lager:log(sink_event, error, self(), "Sink test message 2", []),
{ok, File1} = file:read_file("test1.log"),
{ok, File2} = file:read_file("test2.log"),
{ok, SinkFile} = file:read_file("test3.log"),
{ok, File1Old} = file:read_file("test1.log.0"),
{ok, File1} = file:read_file(State#state.log1),
{ok, File2} = file:read_file(State#state.log2),
{ok, SinkFile} = file:read_file(State#state.sink),
{ok, File1Old} = file:read_file(State#state.log1r),
have_no_log(File1, <<"Test message 1">>), have_no_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>), have_log(File1, <<"Test message 2">>),
@ -66,19 +103,21 @@ rotate_test_() ->
have_log(SinkFile, <<"Sink test message 1">>), have_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>) have_log(SinkFile, <<"Sink test message 2">>)
end},
{"Rotate sink",
end}
end,
fun(State) ->
{"Rotate sink",
fun() -> fun() ->
lager:log(error, self(), "Test message 1"), lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []), lager:log(sink_event, error, self(), "Sink test message 1", []),
lager:rotate_sink(sink_event), lager:rotate_sink(sink_event),
ok = wait_until(fun() -> filelib:is_regular("test3.log.0") end, 10),
ok = wait_until(fun() -> filelib:is_regular(State#state.sinkr) end, 10),
lager:log(error, self(), "Test message 2"), lager:log(error, self(), "Test message 2"),
lager:log(sink_event, error, self(), "Sink test message 2", []), lager:log(sink_event, error, self(), "Sink test message 2", []),
{ok, File1} = file:read_file("test1.log"),
{ok, File2} = file:read_file("test2.log"),
{ok, SinkFile} = file:read_file("test3.log"),
{ok, SinkFileOld} = file:read_file("test3.log.0"),
{ok, File1} = file:read_file(State#state.log1),
{ok, File2} = file:read_file(State#state.log2),
{ok, SinkFile} = file:read_file(State#state.sink),
{ok, SinkFileOld} = file:read_file(State#state.sinkr),
have_log(File1, <<"Test message 1">>), have_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>), have_log(File1, <<"Test message 2">>),
@ -91,21 +130,23 @@ rotate_test_() ->
have_no_log(SinkFile, <<"Sink test message 1">>), have_no_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>) have_log(SinkFile, <<"Sink test message 2">>)
end},
{"Rotate all",
end}
end,
fun(State) ->
{"Rotate all",
fun() -> fun() ->
lager:log(error, self(), "Test message 1"), lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []), lager:log(sink_event, error, self(), "Sink test message 1", []),
lager:rotate_all(), lager:rotate_all(),
ok = wait_until(fun() -> filelib:is_regular("test3.log.0") end, 10),
ok = wait_until(fun() -> filelib:is_regular(State#state.sinkr) end, 10),
lager:log(error, self(), "Test message 2"), lager:log(error, self(), "Test message 2"),
lager:log(sink_event, error, self(), "Sink test message 2", []), lager:log(sink_event, error, self(), "Sink test message 2", []),
{ok, File1} = file:read_file("test1.log"),
{ok, File2} = file:read_file("test2.log"),
{ok, SinkFile} = file:read_file("test3.log"),
{ok, File1Old} = file:read_file("test1.log.0"),
{ok, File2Old} = file:read_file("test2.log.0"),
{ok, SinkFileOld} = file:read_file("test3.log.0"),
{ok, File1} = file:read_file(State#state.log1),
{ok, File2} = file:read_file(State#state.log2),
{ok, SinkFile} = file:read_file(State#state.sink),
{ok, File1Old} = file:read_file(State#state.log1r),
{ok, File2Old} = file:read_file(State#state.log2r),
{ok, SinkFileOld} = file:read_file(State#state.sinkr),
have_no_log(File1, <<"Test message 1">>), have_no_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>), have_log(File1, <<"Test message 2">>),
@ -125,7 +166,9 @@ rotate_test_() ->
have_log(File2Old, <<"Test message 1">>), have_log(File2Old, <<"Test message 1">>),
have_no_log(File2Old, <<"Test message 2">>) have_no_log(File2Old, <<"Test message 2">>)
end}]}.
end}
end
]}.
have_log(Data, Log) -> have_log(Data, Log) ->
{_,_} = binary:match(Data, Log). {_,_} = binary:match(Data, Log).

Cargando…
Cancelar
Guardar