summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Fedotov <hairyhum@gmail.com>2019-06-27 13:43:29 -0400
committerDaniil Fedotov <hairyhum@gmail.com>2019-06-27 13:43:29 -0400
commit96612b28c01dc4bda4f6c96d291128bea303e404 (patch)
tree1f5923ee4b401a2c82b7885b420e8a3109447fd5
parent7a96d094b8f895623c98371f5af0aafcd17c16b9 (diff)
downloadrabbitmq-server-git-96612b28c01dc4bda4f6c96d291128bea303e404.tar.gz
Stream log for N seconds. Fix line cropping when reading entire log.
-rw-r--r--src/rabbit_log_tail.erl57
1 files changed, 33 insertions, 24 deletions
diff --git a/src/rabbit_log_tail.erl b/src/rabbit_log_tail.erl
index d0fb55ec84..555164213b 100644
--- a/src/rabbit_log_tail.erl
+++ b/src/rabbit_log_tail.erl
@@ -1,19 +1,23 @@
-module(rabbit_log_tail).
-export([tail_n_lines/2]).
--export([init_tail_stream/3]).
+-export([init_tail_stream/4]).
-define(GUESS_OFFSET, 200).
-init_tail_stream(Filename, Pid, Ref) ->
+init_tail_stream(Filename, Pid, Ref, Duration) ->
RPCProc = self(),
Reader = spawn(fun() ->
link(Pid),
case file:open(Filename, [read, binary]) of
{ok, File} ->
+ TimeLimit = case Duration of
+ infinity -> infinity;
+ _ -> erlang:system_time(second) + Duration
+ end,
{ok, _} = file:position(File, eof),
RPCProc ! {Ref, opened},
- read_loop(File, Pid, Ref);
+ read_loop(File, Pid, Ref, TimeLimit);
{error, _} = Err ->
RPCProc ! {Ref, Err}
end
@@ -26,16 +30,20 @@ init_tail_stream(Filename, Pid, Ref) ->
{error, timeout}
end.
-read_loop(File, Pid, Ref) ->
- case file:read(File, ?GUESS_OFFSET) of
- {ok, Data} ->
- Pid ! {Ref, Data, confinue},
- read_loop(File, Pid, Ref);
- eof ->
- timer:sleep(1000),
- read_loop(File, Pid, Ref);
- {error, _} = Err ->
- Pid ! {Ref, Err, finished}
+read_loop(File, Pid, Ref, TimeLimit) ->
+ case is_integer(TimeLimit) andalso erlang:system_time(second) > TimeLimit of
+ true -> Pid ! {Ref, <<>>, finished};
+ false ->
+ case file:read(File, ?GUESS_OFFSET) of
+ {ok, Data} ->
+ Pid ! {Ref, Data, confinue},
+ read_loop(File, Pid, Ref, TimeLimit);
+ eof ->
+ timer:sleep(1000),
+ read_loop(File, Pid, Ref, TimeLimit);
+ {error, _} = Err ->
+ Pid ! {Ref, Err, finished}
+ end
end.
tail_n_lines(Filename, N) ->
@@ -46,7 +54,7 @@ tail_n_lines(Filename, N) ->
Result = reverse_read_n_lines(N, N, File, Eof, Eof),
file:close(File),
Result;
- Error -> Error
+ {error, _} = Error -> Error
end.
reverse_read_n_lines(N, OffsetN, File, Position, Eof) ->
@@ -63,7 +71,7 @@ reverse_read_n_lines(N, OffsetN, File, Position, Eof) ->
_ ->
reverse_read_n_lines(N, N - NLines + 1, File, GuessPosition, Eof)
end;
- Error -> Error
+ {error, _} = Error -> Error
end.
read_from_position(File, GuessPosition, Eof) ->
@@ -71,15 +79,16 @@ read_from_position(File, GuessPosition, Eof) ->
read_lines_from_position(File, GuessPosition, Eof) ->
case read_from_position(File, GuessPosition, Eof) of
- {ok, Data} -> {ok, crop_lines(Data)};
- Error -> Error
- end.
-
-crop_lines(Data) ->
- %% Drop the first line, because it's most likely partial.
- case binary:split(Data, <<"\n">>, [global, trim]) of
- [_|Rest] -> Rest;
- [] -> []
+ {ok, Data} ->
+ Lines = binary:split(Data, <<"\n">>, [global, trim]),
+ case {GuessPosition, Lines} of
+ %% If position is 0 - there are no partial lines
+ {0, _} -> {ok, Lines};
+ %% Remove first line as it can be partial
+ {_, [_ | Rest]} -> {ok, Rest};
+ {_, []} -> {ok, []}
+ end;
+ {error, _} = Error -> Error
end.
offset(Base, N) ->