Save log configs to DETS
This commit is contained in:
parent
2a80282b8e
commit
37a16d1924
|
@ -6,22 +6,35 @@
|
||||||
-export([handle_info/2, handle_cast/2, handle_call/3]).
|
-export([handle_info/2, handle_cast/2, handle_call/3]).
|
||||||
-export([code_change/3]).
|
-export([code_change/3]).
|
||||||
|
|
||||||
|
-define(INTERVAL, 60000). % One minute
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
gen_server:start_link(?MODULE, [], []).
|
gen_server:start_link(?MODULE, [], []).
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
register(config, self()),
|
register(config, self()),
|
||||||
{ok, []}.
|
{ok, Storage} = application:get_env(log_monitor, storage),
|
||||||
|
{ok, Logfiles} = dets:open_file(Storage, []),
|
||||||
|
%% erlang:send_after(?INTERVAL, self(), trigger),
|
||||||
|
{ok, [Logfiles]}.
|
||||||
|
|
||||||
|
handle_info(trigger, State) ->
|
||||||
|
erlang:send_after(?INTERVAL, self(), trigger),
|
||||||
|
{noreply, State};
|
||||||
handle_info(_Msg, State) ->
|
handle_info(_Msg, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
handle_cast(_Msg, State) ->
|
handle_cast(_Msg, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
handle_call({monitor, Path}, _From, State) ->
|
handle_call({monitor, File}, _From, [Logfiles]) ->
|
||||||
supervisor:start_child(logfiles_sup, [Path]),
|
case dets:lookup(Logfiles, File) of
|
||||||
{reply, ok, State}.
|
[] ->
|
||||||
|
dets:insert(Logfiles, {File, "ERROR"}),
|
||||||
|
supervisor:start_child(logfiles_sup, [File]),
|
||||||
|
{reply, ok, [Logfiles]};
|
||||||
|
_ -> {reply, duplicate, [Logfiles]}
|
||||||
|
end.
|
||||||
|
|
||||||
terminate(_Reason, _State) ->
|
terminate(_Reason, _State) ->
|
||||||
shutdown.
|
shutdown.
|
||||||
|
@ -29,6 +42,6 @@ terminate(_Reason, _State) ->
|
||||||
code_change(_OldVsn, State, _Extra) ->
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
{ok, State}.
|
{ok, State}.
|
||||||
|
|
||||||
monitor_log(Path) ->
|
monitor_log(File) ->
|
||||||
config ! {monitor, Path},
|
config ! {monitor, File},
|
||||||
gen_server:call(config, {monitor, Path}).
|
gen_server:call(config, {monitor, File}).
|
||||||
|
|
|
@ -5,31 +5,35 @@
|
||||||
-export([handle_info/2, handle_cast/2, handle_call/3]).
|
-export([handle_info/2, handle_cast/2, handle_call/3]).
|
||||||
-export([code_change/3]).
|
-export([code_change/3]).
|
||||||
|
|
||||||
|
-record(log, {file, error_regex}).
|
||||||
|
|
||||||
|
%% start_link(File, ErrorRegex) ->
|
||||||
start_link(File) ->
|
start_link(File) ->
|
||||||
gen_server:start_link(?MODULE, [File], []).
|
ErrorRegex = "ERROR",
|
||||||
|
gen_server:start_link(?MODULE, [#log{file = File, error_regex = ErrorRegex}], []).
|
||||||
|
|
||||||
init([File]) ->
|
init([Log]) ->
|
||||||
{ok, [off, File]}.
|
{ok, [off, Log]}.
|
||||||
|
|
||||||
handle_info({log_line, Text}, [off, File]) ->
|
handle_info({log_line, Text}, [off, Log = #log{error_regex = ErrorRegex}]) ->
|
||||||
case isError(Text) of
|
case isError(Text, ErrorRegex) of
|
||||||
true ->
|
true ->
|
||||||
{ok, Timer} = timer:send_after(1000, {timeout}),
|
{ok, Timer} = timer:send_after(1000, {timeout}),
|
||||||
{noreply, [on, File, Text, Timer]};
|
{noreply, [on, Log, Text, Timer]};
|
||||||
false -> {noreply, [off, File]}
|
false -> {noreply, [off, Log]}
|
||||||
end;
|
end;
|
||||||
handle_info({log_line, Text}, [on, File, Error, Timer]) ->
|
handle_info({log_line, Text}, [on, Log = #log{error_regex = ErrorRegex}, Error, Timer]) ->
|
||||||
case isError(Text) of
|
case isError(Text, ErrorRegex) of
|
||||||
true ->
|
true ->
|
||||||
timer:clean(Timer),
|
timer:clean(Timer),
|
||||||
{ok, NewTimer} = timer:send_after(1000, {timeout}),
|
{ok, NewTimer} = timer:send_after(1000, {timeout}),
|
||||||
{noreply, [on, File, Error ++ "\n" ++ Text, NewTimer]};
|
{noreply, [on, Log, Error ++ "\n" ++ Text, NewTimer]};
|
||||||
false ->
|
false ->
|
||||||
{noreply, [on, File, Error ++ "\n" ++ Text, Timer]}
|
{noreply, [on, Log, Error ++ "\n" ++ Text, Timer]}
|
||||||
end;
|
end;
|
||||||
handle_info({timeout}, [on, File, Error, _Timer]) ->
|
handle_info({timeout}, [on, Log = #log{file = File}, Error, _Timer]) ->
|
||||||
mailer ! {error, File, Error},
|
mailer ! {error, File, Error},
|
||||||
{noreply, [off, File]}.
|
{noreply, [off, Log]}.
|
||||||
|
|
||||||
handle_cast(_Msg, State) ->
|
handle_cast(_Msg, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
@ -43,8 +47,8 @@ terminate(_Reason, _State) ->
|
||||||
code_change(_OldVsn, State, _Extra) ->
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
{ok, State}.
|
{ok, State}.
|
||||||
|
|
||||||
isError(Text) ->
|
isError(Text, ErrorRegex) ->
|
||||||
case re:run(Text, "ERROR") of %% TODO
|
case re:run(Text, ErrorRegex) of
|
||||||
{match, _} ->
|
{match, _} ->
|
||||||
true;
|
true;
|
||||||
nomatch ->
|
nomatch ->
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[
|
[
|
||||||
{ log_monitor,
|
{ log_monitor,
|
||||||
[
|
[
|
||||||
|
{storage, "/tmp/logfiles"},
|
||||||
{email_config,
|
{email_config,
|
||||||
[
|
[
|
||||||
{sender, "me@example.com"},
|
{sender, "me@example.com"},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user