Comments skeleton

This commit is contained in:
Fabio Salvini 2017-07-02 10:42:13 +02:00
parent 8d828abea1
commit 006a241293
11 changed files with 621 additions and 76 deletions

View File

@ -1,5 +1,5 @@
TODO
=====
- Fix gatherer state.
- Limit number of emails that can be sent in a period of time.
- gen_fsm for gatherer?

View File

@ -1,45 +1,98 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(config).
-behaviour(gen_server).
-include_lib("mnesia_tables.hrl").
-export([status/0]).
-export([reload/0]).
-export([start_link/0, init/1, terminate/2]).
-export([handle_info/2, handle_cast/2, handle_call/3]).
-export([code_change/3]).
%% API
-export([start_link/0]).
-export([status/0, reload/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {statuses}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link() ->
gen_server:start_link(?MODULE, [], []).
%%--------------------------------------------------------------------
%% @doc
%% Get the status of the log files
%%
%% @spec status() -> [{Logfile, Status}]
%% @end
%%--------------------------------------------------------------------
status() ->
gen_server:call(config, {get_statuses}).
%%--------------------------------------------------------------------
%% @doc
%% Reload the configuration
%%
%% @spec reload() -> ok
%% @end
%%--------------------------------------------------------------------
reload() ->
gen_server:call(config, {reload}).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% @end
%%--------------------------------------------------------------------
init([]) ->
register(config, self()),
Statuses = ets:new(log_statuses, []),
timer:apply_after(1000, ?MODULE, reload, []),
{ok, #state{statuses = Statuses}}.
handle_info({watcher_init, File}, State = #state{statuses = Statuses}) ->
case ets:lookup(Statuses, File) of
%% If the File has been removed, do nothing
[] -> ok;
_ -> ets:insert(Statuses, {File, active})
end,
{noreply, State};
handle_info({watcher_terminate, File}, State = #state{statuses = Statuses}) ->
case ets:lookup(Statuses, File) of
%% If the File has been removed, do nothing
[] -> ok;
_ -> ets:insert(Statuses, {File, inactive})
end,
{noreply, State};
handle_info(_Msg, State) ->
{noreply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @spec handle_call(Request, From, State) ->
%% {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_call({reload}, _From, State = #state{statuses = Statuses}) ->
{ok, File} = application:get_env(log_monitor, logfiles_config),
{ok, Terms} = file:consult(File),
@ -56,21 +109,80 @@ handle_call({reload}, _From, State = #state{statuses = Statuses}) ->
manage_existing_logfiles(proplists:get_value(existing, LogfilesPartitions), Statuses),
manage_new_logfiles(proplists:get_value(new, LogfilesPartitions), Statuses),
{reply, ok, State};
handle_call({get_statuses}, _From, State = #state{statuses = Statuses}) ->
{reply, ets:tab2list(Statuses), State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @spec handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_info({watcher_init, File}, State = #state{statuses = Statuses}) ->
case ets:lookup(Statuses, File) of
%% If the File has been removed, do nothing
[] -> ok;
_ -> ets:insert(Statuses, {File, active})
end,
{noreply, State};
handle_info({watcher_terminate, File}, State = #state{statuses = Statuses}) ->
case ets:lookup(Statuses, File) of
%% If the File has been removed, do nothing
[] -> ok;
_ -> ets:insert(Statuses, {File, inactive})
end,
{noreply, State};
handle_info(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
shutdown.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
status() ->
gen_server:call(config, {get_statuses}).
reload() ->
gen_server:call(config, {reload}).
%%%===================================================================
%%% Internal functions
%%%===================================================================
compare_groups(Groups) ->
Old = list_groups(),
Deleted = lists:filter(fun(Name) -> not lists:any(fun(#log_monitor_group{name = N, email_receivers = _}) -> N == Name end, Groups) end, Old),

View File

@ -1,18 +1,102 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(gatherer).
-behaviour(gen_server).
-export([start_link/2, init/1, terminate/2]).
-export([handle_info/2, handle_cast/2, handle_call/3]).
-export([code_change/3]).
%% API
-export([start_link/2]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(log, {file, error_regex}).
%% -record(state, {}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @spec start_link(File, ErrorRegex) -> {ok, Pid} |
%% ignore |
%% {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link(File, ErrorRegex) ->
gen_server:start_link(?MODULE, [#log{file = File, error_regex = ErrorRegex}], []).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% @end
%%--------------------------------------------------------------------
init([Log]) ->
{ok, [off, Log]}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @spec handle_call(Request, From, State) ->
%% {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @spec handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_info({log_line, Text}, [off, Log = #log{error_regex = ErrorRegex}]) ->
case isError(Text, ErrorRegex) of
true ->
@ -36,18 +120,34 @@ handle_info({timeout}, [on, Log = #log{file = File}, Error, Timer, SafeTimer]) -
mailer ! {error, File, Error},
{noreply, [off, Log]}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_call(_Request, _From, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
shutdown.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
isError(Text, ErrorRegex) ->
case re:run(Text, ErrorRegex) of
{match, _} ->

View File

@ -1,8 +1,10 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%% @doc log_monitor public API
%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(log_monitor_app).
-behaviour(application).
@ -15,7 +17,6 @@
%%====================================================================
%% API
%%====================================================================
start(_StartType, _StartArgs) ->
start_mnesia(),
log_monitor_sup:start_link().
@ -28,7 +29,6 @@ stop(_State) ->
%%====================================================================
%% Internal functions
%%====================================================================
start_mnesia() ->
Nodes = [node()],
%% Stop Mnesia if it is running, cannot create schema otherwise.

View File

@ -1,8 +1,10 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%% @doc log_monitor top level supervisor.
%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(log_monitor_sup).
-behaviour(supervisor).
@ -18,7 +20,6 @@
%%====================================================================
%% API functions
%%====================================================================
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).

View File

@ -1,12 +1,54 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(log_sup).
-behaviour(supervisor).
%% API
-export([start_link/2]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API functions
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the supervisor
%%
%% @spec start_link(File, ErrorRegex) -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link(File, ErrorRegex) ->
supervisor:start_link(?MODULE, [File, ErrorRegex]).
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever a supervisor is started using supervisor:start_link/[2,3],
%% this function is called by the new process to find out about
%% restart strategy, maximum restart intensity, and child
%% specifications.
%%
%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
%% ignore |
%% {error, Reason}
%% @end
%%--------------------------------------------------------------------
init([File, ErrorRegex]) ->
SupFlags = #{strategy => one_for_one},
ChildSpecs = [#{
@ -24,3 +66,7 @@ init([File, ErrorRegex]) ->
modules => [watcher]
}],
{ok, {SupFlags, ChildSpecs}}.
%%%===================================================================
%%% Internal functions
%%%===================================================================

View File

@ -1,22 +1,45 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(logfiles_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
-export([init/1]).
-export([add_child/1, remove_child/1]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API functions
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the supervisor
%%
%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
SupFlags = #{
strategy => one_for_one,
intensity => 0,
period => 1
},
ChildSpecs = [],
{ok, {SupFlags, ChildSpecs}}.
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%%--------------------------------------------------------------------
%% @doc
%% Add a child to the supervisor
%%
%% @spec add_child(Args) -> void()
%% @end
%%--------------------------------------------------------------------
add_child(Args = [File, _ErrorRegex]) ->
supervisor:start_child(
?MODULE,
@ -29,5 +52,41 @@ add_child(Args = [File, _ErrorRegex]) ->
}
).
%%--------------------------------------------------------------------
%% @doc
%% Remove a child from the supervisor
%%
%% @spec remove_child(File) -> void()
%% @end
%%--------------------------------------------------------------------
remove_child(File) ->
supervisor:terminate_child(?MODULE, File).
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever a supervisor is started using supervisor:start_link/[2,3],
%% this function is called by the new process to find out about
%% restart strategy, maximum restart intensity, and child
%% specifications.
%%
%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
%% ignore |
%% {error, Reason}
%% @end
%%--------------------------------------------------------------------
init([]) ->
SupFlags = #{
strategy => one_for_one,
intensity => 0,
period => 1
},
ChildSpecs = [],
{ok, {SupFlags, ChildSpecs}}.
%%%===================================================================
%%% Internal functions
%%%===================================================================

View File

@ -1,20 +1,101 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(mailer).
-behaviour(gen_server).
-include_lib("mnesia_tables.hrl").
-export([start_link/0, init/1, terminate/2]).
-export([handle_info/2, handle_cast/2, handle_call/3]).
-export([code_change/3]).
%% API
-export([start_link/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(state, {}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link() ->
gen_server:start_link(?MODULE, [], []).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% @end
%%--------------------------------------------------------------------
init([]) ->
register(mailer, self()),
timer:send_after(1000, {send_emails}),
{ok, []}.
{ok, #state{}}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @spec handle_call(Request, From, State) ->
%% {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @spec handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_info({error, File, Text}, State) ->
mnesia:activity(
transaction,
@ -34,18 +115,34 @@ handle_info({send_emails}, State) ->
end,
{noreply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_call(_Request, _From, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
shutdown.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
emails_to_send() ->
mnesia:activity(
transaction,

View File

@ -1,3 +1,11 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-ifndef(MNESIA_HRL).
-define(MNESIA_HRL, 1).

View File

@ -1,9 +1,32 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(utils).
%% API
-export([flatten/1]).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Flattens a list.
%%
%% @spec flatten(X) -> list()
%% @end
%%--------------------------------------------------------------------
flatten(X) -> flatten(X,[]).
%%%===================================================================
%%% Internal functions
%%%===================================================================
flatten([],Acc) -> Acc;
flatten([[]|T],Acc) -> flatten(T, Acc);
flatten([[_|_]=H|T],Acc) -> flatten(T, flatten(H,Acc));

View File

@ -1,13 +1,55 @@
%%%-------------------------------------------------------------------
%%% @author Fabio Salvini <fs@fabiosalvini.com>
%%% @copyright (C) 2017, Fabio Salvini
%%% @doc
%%%
%%% @end
%%% Created : 2 Jul 2017 by Fabio Salvini <fs@fabiosalvini.com>
%%%-------------------------------------------------------------------
-module(watcher).
-behaviour(gen_server).
-export([start_link/2, init/1, terminate/2]).
-export([handle_info/2, handle_cast/2, handle_call/3]).
-export([code_change/3]).
%% API
-export([start_link/2]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @spec start_link(SupPid, File) -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link(SupPid, File) ->
gen_server:start_link(?MODULE, [SupPid, File], []).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% @end
%%--------------------------------------------------------------------
init([SupPid, File]) ->
timer:sleep(1000),
config ! {watcher_init, File},
@ -15,6 +57,47 @@ init([SupPid, File]) ->
Port = open_port({spawn, Cmd}, [stderr_to_stdout, exit_status, binary]),
{ok, [File, SupPid, Port]}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @spec handle_call(Request, From, State) ->
%% {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @spec handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_info(Msg, [File, SupPid, Port]) ->
case Msg of
{Port, {data, Text}} ->
@ -25,18 +108,34 @@ handle_info(Msg, [File, SupPid, Port]) ->
{stop, tail_exit, [File]}
end.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_call(_Request, _From, State) ->
{noreply, State}.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
terminate(_Reason, [File]) ->
config ! {watcher_terminate, File},
shutdown.
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
gatherer_pid(SupPid) ->
hd([Pid || {Id, Pid, _, _} <- supervisor:which_children(SupPid), Id == gatherer]).