浏览代码

Merge pull request #311 from rabbitmq/rotate-command

API to explicitly call log rotation

Reviewed-by: macintux
pull/321/head
Bishop Bors 9 年前
父节点
当前提交
c973e94bb3
共有 3 个文件被更改,包括 181 次插入0 次删除
  1. +30
    -0
      src/lager.erl
  2. +13
    -0
      src/lager_file_backend.erl
  3. +138
    -0
      test/lager_rotate.erl

+ 30
- 0
src/lager.erl 查看文件

@ -22,12 +22,14 @@
-define(LAGER_MD_KEY, '__lager_metadata'). -define(LAGER_MD_KEY, '__lager_metadata').
-define(TRACE_SINK, '__trace_sink'). -define(TRACE_SINK, '__trace_sink').
-define(ROTATE_TIMEOUT, 100000).
%% API %% API
-export([start/0, -export([start/0,
log/3, log/4, log/5, log/3, log/4, log/5,
log_unsafe/4, log_unsafe/4,
md/0, md/1, md/0, md/1,
rotate_handler/1, rotate_handler/2, rotate_sink/1, rotate_all/0,
trace/2, trace/3, trace_file/2, trace_file/3, trace_file/4, trace_console/1, trace_console/2, trace/2, trace/3, trace_file/2, trace_file/3, trace_file/4, trace_console/1, trace_console/2,
list_all_sinks/0, clear_all_traces/0, stop_trace/1, stop_trace/3, status/0, list_all_sinks/0, clear_all_traces/0, stop_trace/1, stop_trace/3, status/0,
get_loglevel/1, get_loglevel/2, set_loglevel/2, set_loglevel/3, set_loglevel/4, get_loglevels/1, get_loglevel/1, get_loglevel/2, set_loglevel/2, set_loglevel/3, set_loglevel/4, get_loglevels/1,
@ -606,3 +608,31 @@ pr_stacktrace(Stacktrace) ->
pr_stacktrace(Stacktrace, {Class, Reason}) -> pr_stacktrace(Stacktrace, {Class, Reason}) ->
lists:flatten( lists:flatten(
pr_stacktrace(Stacktrace) ++ "\n" ++ io_lib:format("~s:~p", [Class, Reason])). pr_stacktrace(Stacktrace) ++ "\n" ++ io_lib:format("~s:~p", [Class, Reason])).
rotate_sink(Sink) ->
Handlers = lager_config:global_get(handlers),
RotateHandlers = lists:filtermap(
fun({Handler,_,S}) when S == Sink -> {true, {Handler, Sink}};
(_) -> false
end,
Handlers),
rotate_handlers(RotateHandlers).
rotate_all() ->
rotate_handlers(lists:map(fun({H,_,S}) -> {H, S} end,
lager_config:global_get(handlers))).
rotate_handlers(Handlers) ->
[ rotate_handler(Handler, Sink) || {Handler, Sink} <- Handlers ].
rotate_handler(Handler) ->
Handlers = lager_config:global_get(handlers),
case lists:keyfind(Handler, 1, Handlers) of
{Handler, _, Sink} -> rotate_handler(Handler, Sink);
false -> ok
end.
rotate_handler(Handler, Sink) ->
gen_event:call(Sink, Handler, rotate, ?ROTATE_TIMEOUT).

+ 13
- 0
src/lager_file_backend.erl 查看文件

@ -142,6 +142,9 @@ handle_call({set_loghwm, Hwm}, #state{shaper=Shaper, name=Name} = State) ->
?INT_LOG(notice, "Changed loghwm of ~s to ~p", [Name, Hwm]), ?INT_LOG(notice, "Changed loghwm of ~s to ~p", [Name, Hwm]),
{ok, {last_loghwm, Shaper#lager_shaper.hwm}, State#state{shaper=NewShaper}} {ok, {last_loghwm, Shaper#lager_shaper.hwm}, State#state{shaper=NewShaper}}
end; end;
handle_call(rotate, State = #state{name=File}) ->
{ok, NewState} = handle_info({rotate, File}, State),
{ok, ok, NewState};
handle_call(_Request, State) -> handle_call(_Request, State) ->
{ok, ok, State}. {ok, ok, State}.
@ -637,6 +640,16 @@ filesystem_test_() ->
?assert(filelib:is_regular("test.log.0")) ?assert(filelib:is_regular("test.log.0"))
end end
}, },
{"rotation call should work",
fun() ->
gen_event:add_handler(lager_event, {lager_file_backend, "test.log"}, [{file, "test.log"}, {level, info}, {check_interval, 1000}]),
lager:log(error, self(), "Test message1"),
lager:log(error, self(), "Test message1"),
gen_event:call(lager_event, {lager_file_backend, "test.log"}, rotate, infinity),
lager:log(error, self(), "Test message1"),
?assert(filelib:is_regular("test.log.0"))
end
},
{"sync_on option should work", {"sync_on option should work",
fun() -> fun() ->
gen_event:add_handler(lager_event, lager_file_backend, [{file, "test.log"}, {level, info}, {sync_on, "=info"}, {check_interval, 5000}, {sync_interval, 5000}]), gen_event:add_handler(lager_event, lager_file_backend, [{file, "test.log"}, {level, info}, {sync_on, "=info"}, {check_interval, 5000}, {sync_interval, 5000}]),

+ 138
- 0
test/lager_rotate.erl 查看文件

@ -0,0 +1,138 @@
-module(lager_rotate).
-compile(export_all).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
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)
end,
[{"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"}),
timer:sleep(1000),
true = filelib:is_regular("test1.log.0"),
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"),
have_no_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>),
have_log(File2, <<"Test message 1">>),
have_log(File2, <<"Test message 2">>),
have_log(File1Old, <<"Test message 1">>),
have_no_log(File1Old, <<"Test message 2">>),
have_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>)
end},
{"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),
timer:sleep(1000),
true = filelib:is_regular("test3.log.0"),
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"),
have_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>),
have_log(File2, <<"Test message 1">>),
have_log(File2, <<"Test message 2">>),
have_log(SinkFileOld, <<"Sink test message 1">>),
have_no_log(SinkFileOld, <<"Sink test message 2">>),
have_no_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>)
end},
{"Rotate all",
fun() ->
lager:log(error, self(), "Test message 1"),
lager:log(sink_event, error, self(), "Sink test message 1", []),
lager:rotate_all(),
timer:sleep(1000),
true = filelib:is_regular("test3.log.0"),
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"),
have_no_log(File1, <<"Test message 1">>),
have_log(File1, <<"Test message 2">>),
have_no_log(File2, <<"Test message 1">>),
have_log(File2, <<"Test message 2">>),
have_no_log(SinkFile, <<"Sink test message 1">>),
have_log(SinkFile, <<"Sink test message 2">>),
have_log(SinkFileOld, <<"Sink test message 1">>),
have_no_log(SinkFileOld, <<"Sink test message 2">>),
have_log(File1Old, <<"Test message 1">>),
have_no_log(File1Old, <<"Test message 2">>),
have_log(File2Old, <<"Test message 1">>),
have_no_log(File2Old, <<"Test message 2">>)
end}]}.
have_log(Data, Log) ->
{_,_} = binary:match(Data, Log).
have_no_log(Data, Log) ->
nomatch = binary:match(Data, Log).

正在加载...
取消
保存