diff --git a/apps/log_monitor/src/config.erl b/apps/log_monitor/src/config.erl index c9caa0e..41dce6e 100644 --- a/apps/log_monitor/src/config.erl +++ b/apps/log_monitor/src/config.erl @@ -6,22 +6,35 @@ -export([handle_info/2, handle_cast/2, handle_call/3]). -export([code_change/3]). +-define(INTERVAL, 60000). % One minute + start_link() -> gen_server:start_link(?MODULE, [], []). init([]) -> 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) -> {noreply, State}. handle_cast(_Msg, State) -> {noreply, State}. -handle_call({monitor, Path}, _From, State) -> - supervisor:start_child(logfiles_sup, [Path]), - {reply, ok, State}. +handle_call({monitor, File}, _From, [Logfiles]) -> + case dets:lookup(Logfiles, File) of + [] -> + dets:insert(Logfiles, {File, "ERROR"}), + supervisor:start_child(logfiles_sup, [File]), + {reply, ok, [Logfiles]}; + _ -> {reply, duplicate, [Logfiles]} + end. terminate(_Reason, _State) -> shutdown. @@ -29,6 +42,6 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -monitor_log(Path) -> - config ! {monitor, Path}, - gen_server:call(config, {monitor, Path}). +monitor_log(File) -> + config ! {monitor, File}, + gen_server:call(config, {monitor, File}). diff --git a/apps/log_monitor/src/gatherer.erl b/apps/log_monitor/src/gatherer.erl index c52210f..2273cd6 100644 --- a/apps/log_monitor/src/gatherer.erl +++ b/apps/log_monitor/src/gatherer.erl @@ -5,31 +5,35 @@ -export([handle_info/2, handle_cast/2, handle_call/3]). -export([code_change/3]). +-record(log, {file, error_regex}). + +%% start_link(File, ErrorRegex) -> start_link(File) -> - gen_server:start_link(?MODULE, [File], []). + ErrorRegex = "ERROR", + gen_server:start_link(?MODULE, [#log{file = File, error_regex = ErrorRegex}], []). -init([File]) -> - {ok, [off, File]}. +init([Log]) -> + {ok, [off, Log]}. -handle_info({log_line, Text}, [off, File]) -> - case isError(Text) of +handle_info({log_line, Text}, [off, Log = #log{error_regex = ErrorRegex}]) -> + case isError(Text, ErrorRegex) of true -> {ok, Timer} = timer:send_after(1000, {timeout}), - {noreply, [on, File, Text, Timer]}; - false -> {noreply, [off, File]} + {noreply, [on, Log, Text, Timer]}; + false -> {noreply, [off, Log]} end; -handle_info({log_line, Text}, [on, File, Error, Timer]) -> - case isError(Text) of +handle_info({log_line, Text}, [on, Log = #log{error_regex = ErrorRegex}, Error, Timer]) -> + case isError(Text, ErrorRegex) of true -> timer:clean(Timer), {ok, NewTimer} = timer:send_after(1000, {timeout}), - {noreply, [on, File, Error ++ "\n" ++ Text, NewTimer]}; + {noreply, [on, Log, Error ++ "\n" ++ Text, NewTimer]}; false -> - {noreply, [on, File, Error ++ "\n" ++ Text, Timer]} + {noreply, [on, Log, Error ++ "\n" ++ Text, Timer]} end; -handle_info({timeout}, [on, File, Error, _Timer]) -> +handle_info({timeout}, [on, Log = #log{file = File}, Error, _Timer]) -> mailer ! {error, File, Error}, - {noreply, [off, File]}. + {noreply, [off, Log]}. handle_cast(_Msg, State) -> {noreply, State}. @@ -43,8 +47,8 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -isError(Text) -> - case re:run(Text, "ERROR") of %% TODO +isError(Text, ErrorRegex) -> + case re:run(Text, ErrorRegex) of {match, _} -> true; nomatch -> diff --git a/config/sys.config b/config/sys.config index eb7bcfa..967c843 100644 --- a/config/sys.config +++ b/config/sys.config @@ -1,6 +1,7 @@ [ { log_monitor, [ + {storage, "/tmp/logfiles"}, {email_config, [ {sender, "me@example.com"},