Use external configuration for the log to monitor
This commit is contained in:
parent
fa1bfa9d25
commit
1e26998649
3
TODO.md
3
TODO.md
|
@ -1,7 +1,6 @@
|
|||
TODO
|
||||
=====
|
||||
|
||||
- Allow to enable / disabled logfiles.
|
||||
- gatherer.erl:29 Error on ++.
|
||||
- Limit number of emails that can be sent in a period of time.
|
||||
- Store the logfiles in a configuration file.
|
||||
- gen_fsm for gatherer?
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
-include_lib("mnesia_tables.hrl").
|
||||
|
||||
-export([create_group/2, monitor_log/3, unmonitor_log/1]).
|
||||
-export([logfiles/0]).
|
||||
-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]).
|
||||
|
@ -17,6 +17,7 @@ start_link() ->
|
|||
init([]) ->
|
||||
register(config, self()),
|
||||
Statuses = ets:new(log_statuses, []),
|
||||
%% TODO: reload?
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
|
@ -49,50 +50,22 @@ handle_info(_Msg, State) ->
|
|||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_call({create_group, Name, EmailReceivers}, _From, State) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
case mnesia:read(log_monitor_group, Name) of
|
||||
[] ->
|
||||
mnesia:write(#log_monitor_group{name = Name, email_receivers = EmailReceivers}),
|
||||
handle_call({reload}, _From, State = #state{statuses = Statuses}) ->
|
||||
{ok, File} = application:get_env(log_monitor, logfiles_config),
|
||||
{ok, Terms} = file:consult(File),
|
||||
MonitoredLogs = proplists:get_value(monitored_logs, Terms),
|
||||
Groups = [#log_monitor_group{name = Name, email_receivers = EmailReceivers} || {{group, Name}, {email_receivers, EmailReceivers}, _} <- MonitoredLogs],
|
||||
Logfiles = utils:flatten([[#log_monitor_file{file = F, error_regex = ErrorRegex, group = Name} || {{file, F}, {error_regex, ErrorRegex}} <- Logfiles]
|
||||
|| {{group, Name}, {email_receivers, _}, {logfiles, Logfiles}} <- MonitoredLogs]),
|
||||
GroupsPartitions = compare_groups(Groups),
|
||||
manage_deleted_groups(proplists:get_value(deleted, GroupsPartitions)),
|
||||
manage_existing_groups(proplists:get_value(existing, GroupsPartitions)),
|
||||
manage_new_groups(proplists:get_value(new, GroupsPartitions)),
|
||||
LogfilesPartitions = compare_logfiles(Logfiles),
|
||||
manage_deleted_logfiles(proplists:get_value(deleted, LogfilesPartitions), Statuses),
|
||||
manage_existing_logfiles(proplists:get_value(existing, LogfilesPartitions)),
|
||||
manage_new_logfiles(proplists:get_value(new, LogfilesPartitions), Statuses),
|
||||
{reply, ok, State};
|
||||
_ -> {reply, {error, "Duplicate"}, State}
|
||||
end
|
||||
end);
|
||||
handle_call({monitor, Group, File, ErrorRegex}, _From, State) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
case mnesia:read(log_monitor_group, Group) of
|
||||
[{log_monitor_group, Group, _}] ->
|
||||
case mnesia:read(log_monitor_file, File) of
|
||||
[] ->
|
||||
mnesia:write(#log_monitor_file{
|
||||
file = File,
|
||||
error_regex = ErrorRegex,
|
||||
group = Group,
|
||||
status = enabled}),
|
||||
logfiles_sup:add_child([File, ErrorRegex]),
|
||||
{reply, ok, State};
|
||||
_ -> {reply, {error, "Duplicate"}, State}
|
||||
end;
|
||||
[] -> {reply, {error, "Unknown group"}, State}
|
||||
end
|
||||
end);
|
||||
handle_call({unmonitor, File}, _From, State = #state{statuses = Statuses}) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
case mnesia:read(log_monitor_file, File) of
|
||||
[{log_monitor_file, File, _, _, _}] ->
|
||||
mnesia:delete({log_monitor_file, File}),
|
||||
ets:delete(Statuses, File),
|
||||
logfiles_sup:remove_child(File),
|
||||
{reply, ok, State};
|
||||
_ -> {reply, {error, "File not found"}, State}
|
||||
end
|
||||
end);
|
||||
handle_call({get_statuses}, _From, State = #state{statuses = Statuses}) ->
|
||||
{reply, ets:tab2list(Statuses), State}.
|
||||
|
||||
|
@ -102,14 +75,115 @@ terminate(_Reason, _State) ->
|
|||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
create_group(Name, EmailReceivers) ->
|
||||
gen_server:call(config, {create_group, Name, EmailReceivers}).
|
||||
|
||||
monitor_log(Group, File, ErrorRegex) ->
|
||||
gen_server:call(config, {monitor, Group, File, ErrorRegex}).
|
||||
|
||||
unmonitor_log(File) ->
|
||||
gen_server:call(config, {unmonitor, File}).
|
||||
|
||||
logfiles() ->
|
||||
status() ->
|
||||
gen_server:call(config, {get_statuses}).
|
||||
|
||||
reload() ->
|
||||
gen_server:call(config, {reload}).
|
||||
|
||||
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),
|
||||
Existing = lists:filter(fun(#log_monitor_group{name = Name, email_receivers = _}) -> lists:member(Name, Old) end, Groups),
|
||||
New = lists:filter(fun(#log_monitor_group{name = Name, email_receivers = _}) -> not lists:member(Name, Old) end, Groups),
|
||||
[
|
||||
{deleted, Deleted},
|
||||
{existing, Existing},
|
||||
{new, New}
|
||||
].
|
||||
|
||||
manage_deleted_groups(Groups) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(Name, _Acc) ->
|
||||
mnesia:delete({log_monitor_group, Name})
|
||||
end, [], Groups)
|
||||
end).
|
||||
|
||||
manage_existing_groups(Groups) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(Group, _Acc) ->
|
||||
mnesia:write(Group)
|
||||
end, [], Groups)
|
||||
end).
|
||||
|
||||
manage_new_groups(Groups) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(Group, _Acc) ->
|
||||
mnesia:write(Group)
|
||||
end, [], Groups)
|
||||
end).
|
||||
|
||||
list_groups() ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
mnesia:foldl(
|
||||
fun(#log_monitor_group{name = Name, email_receivers = _}, Acc) ->
|
||||
[Name | Acc]
|
||||
end, [], log_monitor_group)
|
||||
end).
|
||||
|
||||
compare_logfiles(Logfiles) ->
|
||||
Old= list_logfiles(),
|
||||
Deleted = lists:filter(fun(File) -> not lists:any(fun(#log_monitor_file{file = F, error_regex = _, group = _}) -> F == File end, Logfiles) end, Old),
|
||||
Existing = lists:filter(fun(#log_monitor_file{file = File, error_regex = _, group = _}) -> lists:member(File, Old) end, Logfiles),
|
||||
New = lists:filter(fun(#log_monitor_file{file = File, error_regex = _, group = _}) -> not lists:member(File, Old) end, Logfiles),
|
||||
[
|
||||
{deleted, Deleted},
|
||||
{existing, Existing},
|
||||
{new, New}
|
||||
].
|
||||
|
||||
manage_deleted_logfiles(Logfiles, Statuses) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(File, _Acc) ->
|
||||
logfiles_sup:remove_child(File),
|
||||
mnesia:delete({log_monitor_file, File}),
|
||||
ets:delete(Statuses, File)
|
||||
end, [], Logfiles)
|
||||
end).
|
||||
|
||||
manage_existing_logfiles(Logfiles) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(Logfile = #log_monitor_file{file = File, error_regex = ErrorRegex, group = _}, _Acc) ->
|
||||
mnesia:write(Logfile),
|
||||
case mnesia:read(log_monitor_file, File) of
|
||||
[#log_monitor_file{file = File, error_regex = ErrorRegex, group = _}] -> ok;
|
||||
_ ->
|
||||
%% The error regex has changed
|
||||
logfiles_sup:remove_child(File),
|
||||
logfiles_sup:add_child([File, ErrorRegex])
|
||||
end
|
||||
end, [], Logfiles)
|
||||
end).
|
||||
|
||||
manage_new_logfiles(Logfiles, Statuses) ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
lists:foldl(fun(Logfile = #log_monitor_file{file = File, error_regex = ErrorRegex, group = _}, _Acc) ->
|
||||
mnesia:write(Logfile),
|
||||
ets:insert(Statuses, {File, inactive}),
|
||||
logfiles_sup:add_child([File, ErrorRegex])
|
||||
end, [], Logfiles)
|
||||
end).
|
||||
|
||||
list_logfiles() ->
|
||||
mnesia:activity(
|
||||
transaction,
|
||||
fun() ->
|
||||
mnesia:foldl(
|
||||
fun(#log_monitor_file{file = File, error_regex = _, group = _}, Acc) ->
|
||||
[File | Acc]
|
||||
end, [], log_monitor_file)
|
||||
end).
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
[kernel,
|
||||
stdlib,
|
||||
gen_smtp,
|
||||
mnesia
|
||||
mnesia,
|
||||
%% Observer
|
||||
observer, wx, runtime_tools
|
||||
]},
|
||||
{env,[]},
|
||||
{modules, []},
|
||||
|
|
|
@ -90,7 +90,7 @@ send_email(File, Text) ->
|
|||
Connection
|
||||
)
|
||||
catch
|
||||
_Throw ->
|
||||
error:_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
|
@ -107,10 +107,11 @@ receivers(File) ->
|
|||
transaction,
|
||||
fun() ->
|
||||
case mnesia:read(log_monitor_file, File) of
|
||||
[{log_monitor_file, File, _, _, Group}] ->
|
||||
[{log_monitor_file, File, _, Group}] ->
|
||||
case mnesia:read(log_monitor_group, Group) of
|
||||
[{log_monitor_group, Group, EmailReceivers}] ->
|
||||
EmailReceivers
|
||||
EmailReceivers;
|
||||
_ -> throw(file_group_not_found)
|
||||
end;
|
||||
_ -> throw(file_not_found)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
%% Mnesia tables
|
||||
-record(log_monitor_group, {name, email_receivers=[]}).
|
||||
-record(log_monitor_file, {file, error_regex, status, group}).
|
||||
-record(log_monitor_file, {file, error_regex, group}).
|
||||
-record(log_monitor_error, {id, file, text}).
|
||||
|
||||
-endif.
|
||||
|
|
10
apps/log_monitor/src/utils.erl
Normal file
10
apps/log_monitor/src/utils.erl
Normal file
|
@ -0,0 +1,10 @@
|
|||
-module(utils).
|
||||
|
||||
-export([flatten/1]).
|
||||
|
||||
flatten(X) -> flatten(X,[]).
|
||||
|
||||
flatten([],Acc) -> Acc;
|
||||
flatten([[]|T],Acc) -> flatten(T, Acc);
|
||||
flatten([[_|_]=H|T],Acc) -> flatten(T, flatten(H,Acc));
|
||||
flatten([H|T],Acc) -> flatten(T,Acc++[H]) .
|
|
@ -16,7 +16,8 @@
|
|||
{password, ""}]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{logfiles_config, "/home/fsalvini/gitRepos/log_monitor/config/logfiles.config"}
|
||||
]
|
||||
},
|
||||
%% Directory where the application data is stored.
|
||||
|
|
12
config/logfiles.config
Normal file
12
config/logfiles.config
Normal file
|
@ -0,0 +1,12 @@
|
|||
{monitored_logs, [
|
||||
{
|
||||
{group, "Test"},
|
||||
{email_receivers, ["user@example.com"]},
|
||||
{logfiles, [
|
||||
{
|
||||
{file, "/tmp/lines.log"},
|
||||
{error_regex, "ERROR"}
|
||||
}
|
||||
]}
|
||||
}
|
||||
]}.
|
1
config/rebar.lock
Normal file
1
config/rebar.lock
Normal file
|
@ -0,0 +1 @@
|
|||
[].
|
Loading…
Reference in New Issue
Block a user