Save emails to send to Mnesia

This commit is contained in:
Fabio Salvini 2017-06-26 11:39:16 +02:00
parent ccfc089f31
commit ab5d442d9f
4 changed files with 75 additions and 8 deletions

7
TODO.md Normal file
View File

@ -0,0 +1,7 @@
TODO
=====
- Manage problem of "infinite" consecutive errors.
- Limit number of emails that can be sent in a period of time.
- Store the logfiles in a configuration file.
- gen_fsm for gatherer?

View File

@ -31,7 +31,7 @@ stop(_State) ->
start_mnesia() ->
Nodes = [node()],
%% Stop Mnesia if is running, cannot create schema otherwise.
%% Stop Mnesia if it is running, cannot create schema otherwise.
mnesia:stop(),
mnesia:create_schema(Nodes),
mnesia:start(),
@ -46,4 +46,16 @@ start_mnesia() ->
{index, [#log_monitor_file.group]},
{disc_copies, Nodes}
]),
ok = mnesia:wait_for_tables([log_monitor_group, log_monitor_file], 30000).
mnesia:create_table(log_monitor_error,
[
{attributes, record_info(fields, log_monitor_error)},
{disc_copies, Nodes}
]),
ok = mnesia:wait_for_tables(
[
log_monitor_group,
log_monitor_file,
log_monitor_error
],
30000
).

View File

@ -1,6 +1,8 @@
-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]).
@ -10,15 +12,27 @@ start_link() ->
init([]) ->
register(mailer, self()),
timer:send_after(1000, {send_emails}),
{ok, []}.
handle_info({error, File, Text}, []) ->
case send_email(File, Text) of
{error, Reason, Message} ->
error_logger:error_msg("Error sending email: ~s ~p~n", [Reason, Message]);
_ -> ok
handle_info({error, File, Text}, State) ->
mnesia:activity(
transaction,
fun() ->
Id = erlang:monotonic_time(),
mnesia:write(#log_monitor_error{id = Id, file = File, text = Text})
end),
{noreply, State};
handle_info({send_emails}, State) ->
Emails = emails_to_send(),
try send_emails(Emails) of
_ -> timer:send_after(1000, {send_emails})
catch
_Throw ->
error_logger:info_msg("Waiting 60s before sending new emails~n"),
timer:send_after(60000, {send_emails})
end,
{noreply, []}.
{noreply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
@ -32,6 +46,31 @@ terminate(_Reason, _State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
emails_to_send() ->
mnesia:activity(
transaction,
fun() ->
mnesia:foldl(
fun(#log_monitor_error{id = Id, file = File, text = Text}, Acc) ->
[{Id, File, Text}] ++ Acc
end, [], log_monitor_error)
end).
send_emails(Emails) ->
case Emails of
[] -> {ok};
[{Id, File, Text} | Others] ->
case send_email(File, Text) of
{error, Reason, Message} ->
error_logger:error_msg("Error sending email: ~s ~p~n", [Reason, Message]),
throw(cannot_send_email);
_ ->
remove_email(Id),
send_emails(Others),
{ok}
end
end.
send_email(File, Text) ->
{ok, EmailConfig} = application:get_env(log_monitor, email_config),
Sender = proplists:get_value(sender, EmailConfig),
@ -43,3 +82,11 @@ send_email(File, Text) ->
io_lib:format("Subject: Error notification\r\nFrom: Fabio\r\n\r\nLogfile: ~s~nError: ~n~s~n", [File, Text])},
Connection
).
remove_email(Id) ->
mnesia:activity(
transaction,
fun() ->
mnesia:delete({log_monitor_error, Id})
end),
ok.

View File

@ -4,5 +4,6 @@
%% Mnesia tables
-record(log_monitor_group, {name, email_receivers=[]}).
-record(log_monitor_file, {file, error_regex, status, group}).
-record(log_monitor_error, {id, file, text}).
-endif.