From 810b6c0adaeac25c1842f2796c459102f8b70e55 Mon Sep 17 00:00:00 2001 From: Fabio Salvini Date: Mon, 12 Jun 2017 14:27:21 +0200 Subject: [PATCH] Error regex as external parameter and monitoring --- apps/log_monitor/src/config.erl | 39 ++++++++++++++++++------------- apps/log_monitor/src/gatherer.erl | 6 ++--- apps/log_monitor/src/log_sup.erl | 10 ++++---- apps/log_monitor/src/watcher.erl | 12 ++++++---- 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/apps/log_monitor/src/config.erl b/apps/log_monitor/src/config.erl index 41dce6e..c73e438 100644 --- a/apps/log_monitor/src/config.erl +++ b/apps/log_monitor/src/config.erl @@ -1,13 +1,12 @@ -module(config). -behaviour(gen_server). --export([monitor_log/1]). +-export([monitor_log/2]). +-export([logfiles/0]). -export([start_link/0, init/1, terminate/2]). -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, [], []). @@ -15,11 +14,14 @@ init([]) -> register(config, self()), {ok, Storage} = application:get_env(log_monitor, storage), {ok, Logfiles} = dets:open_file(Storage, []), - %% erlang:send_after(?INTERVAL, self(), trigger), - {ok, [Logfiles]}. + Statuses = ets:new(log_statuses, []), + {ok, [Logfiles, Statuses]}. -handle_info(trigger, State) -> - erlang:send_after(?INTERVAL, self(), trigger), +handle_info({watcher_init, File}, State = [_Logfiles, Statuses]) -> + ets:insert(Statuses, {File, enabled}), + {noreply, State}; +handle_info({watcher_terminate, File}, State = [_Logfiles, Statuses]) -> + ets:insert(Statuses, {File, disabled}), {noreply, State}; handle_info(_Msg, State) -> {noreply, State}. @@ -27,14 +29,17 @@ handle_info(_Msg, State) -> handle_cast(_Msg, State) -> {noreply, State}. -handle_call({monitor, File}, _From, [Logfiles]) -> +handle_call({monitor, File, ErrorRegex}, _From, State = [Logfiles, Statuses]) -> case dets:lookup(Logfiles, File) of [] -> - dets:insert(Logfiles, {File, "ERROR"}), - supervisor:start_child(logfiles_sup, [File]), - {reply, ok, [Logfiles]}; - _ -> {reply, duplicate, [Logfiles]} - end. + dets:insert(Logfiles, {File, ErrorRegex}), + ets:insert(Statuses, {File, disabled}), + supervisor:start_child(logfiles_sup, [File, ErrorRegex]), + {reply, ok, State}; + _ -> {reply, duplicate, State} + end; +handle_call({get_statuses}, _From, State = [_Logfiles, Statuses]) -> + {reply, ets:tab2list(Statuses), State}. terminate(_Reason, _State) -> shutdown. @@ -42,6 +47,8 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -monitor_log(File) -> - config ! {monitor, File}, - gen_server:call(config, {monitor, File}). +monitor_log(File, ErrorRegex) -> + gen_server:call(config, {monitor, File, ErrorRegex}). + +logfiles() -> + gen_server:call(config, {get_statuses}). diff --git a/apps/log_monitor/src/gatherer.erl b/apps/log_monitor/src/gatherer.erl index 2273cd6..c28e21b 100644 --- a/apps/log_monitor/src/gatherer.erl +++ b/apps/log_monitor/src/gatherer.erl @@ -1,15 +1,13 @@ -module(gatherer). -behaviour(gen_server). --export([start_link/1, init/1, terminate/2]). +-export([start_link/2, init/1, terminate/2]). -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) -> - ErrorRegex = "ERROR", +start_link(File, ErrorRegex) -> gen_server:start_link(?MODULE, [#log{file = File, error_regex = ErrorRegex}], []). init([Log]) -> diff --git a/apps/log_monitor/src/log_sup.erl b/apps/log_monitor/src/log_sup.erl index 9ae6824..8c1c2b0 100644 --- a/apps/log_monitor/src/log_sup.erl +++ b/apps/log_monitor/src/log_sup.erl @@ -1,17 +1,17 @@ -module(log_sup). -behaviour(supervisor). --export([start_link/1]). +-export([start_link/2]). -export([init/1]). -start_link(File) -> - supervisor:start_link(?MODULE, [File]). +start_link(File, ErrorRegex) -> + supervisor:start_link(?MODULE, [File, ErrorRegex]). -init(File) -> +init([File, ErrorRegex]) -> SupFlags = #{strategy => one_for_one}, ChildSpecs = [#{ id => gatherer, - start => {gatherer, start_link, [File]}, + start => {gatherer, start_link, [File, ErrorRegex]}, restart => permanent, shutdown => 5000 }, diff --git a/apps/log_monitor/src/watcher.erl b/apps/log_monitor/src/watcher.erl index a6eb18b..a7af2c9 100644 --- a/apps/log_monitor/src/watcher.erl +++ b/apps/log_monitor/src/watcher.erl @@ -10,18 +10,19 @@ start_link(SupPid, File) -> init([SupPid, File]) -> timer:sleep(1000), + config ! {watcher_init, File}, Cmd = "/usr/bin/tail -n0 --follow=name " ++ File, Port = open_port({spawn, Cmd}, [stderr_to_stdout, exit_status, binary]), - {ok, [SupPid, Port]}. + {ok, [File, SupPid, Port]}. -handle_info(Msg, [SupPid, Port]) -> +handle_info(Msg, [File, SupPid, Port]) -> case Msg of {Port, {data, Text}} -> GathererPid = gatherer_pid(SupPid), GathererPid ! {log_line, Text}, - {noreply, [SupPid, Port]}; + {noreply, [File, SupPid, Port]}; {Port, {exit_status, _Status}} -> - {stop, tail_exit, []} + {stop, tail_exit, [File]} end. handle_cast(_Msg, State) -> @@ -30,7 +31,8 @@ handle_cast(_Msg, State) -> handle_call(_Request, _From, State) -> {noreply, State}. -terminate(_Reason, _State) -> +terminate(_Reason, [File]) -> + config ! {watcher_terminate, File}, shutdown. code_change(_OldVsn, State, _Extra) ->