浏览代码

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 8 年前
父节点
当前提交
6fac9ebc69
共有 3 个文件被更改,包括 782 次插入599 次删除
  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 查看文件

@ -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,
%% 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
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
%% @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
@ -236,105 +240,118 @@ do_log({log, Event}, #state{name=Name, fd=FD, inode=Inode, flap=Flap,
filesystem_test_() ->
{foreach,
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,
[
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",
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",
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",
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",
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",
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.

+ 573
- 450
src/lager_file_backend.erl
文件差异内容过多而无法显示
查看文件


+ 98
- 55
test/lager_rotate.erl 查看文件

@ -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).
-compile(export_all).
@ -6,54 +26,71 @@
-include_lib("eunit/include/eunit.hrl").
-endif.
-record(state, {
dir :: string(),
log1 :: string(),
log1r :: string(),
log2 :: string(),
log2r :: string(),
sink :: string(),
sinkr :: string()
}).
rotate_test_() ->
{foreach,
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,
[{"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() ->
lager:log(error, self(), "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(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_log(File1, <<"Test message 2">>),
@ -66,19 +103,21 @@ rotate_test_() ->
have_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>)
end},
{"Rotate sink",
end}
end,
fun(State) ->
{"Rotate sink",
fun() ->
lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []),
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(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 2">>),
@ -91,21 +130,23 @@ rotate_test_() ->
have_no_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>)
end},
{"Rotate all",
end}
end,
fun(State) ->
{"Rotate all",
fun() ->
lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []),
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(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_log(File1, <<"Test message 2">>),
@ -125,7 +166,9 @@ rotate_test_() ->
have_log(File2Old, <<"Test message 1">>),
have_no_log(File2Old, <<"Test message 2">>)
end}]}.
end}
end
]}.
have_log(Data, Log) ->
{_,_} = binary:match(Data, Log).

正在加载...
取消
保存