diff --git a/apps/log_monitor/src/config.erl b/apps/log_monitor/src/config.erl index a2ee1c5..ffb1adc 100644 --- a/apps/log_monitor/src/config.erl +++ b/apps/log_monitor/src/config.erl @@ -184,6 +184,16 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Compare the old and new groups. +%% +%% @spec compare_groups(Logfiles) -> +%% [{deleted, D}, {existing, E}, {new, N}] +%% @end +%%-------------------------------------------------------------------- compare_groups(Groups) -> Old = list_groups(), Deleted = lists:filter(fun(Name) -> not lists:any(fun(Group) -> Group#log_monitor_group.name == Name end, Groups) end, Old), @@ -195,6 +205,15 @@ compare_groups(Groups) -> {new, New} ]. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the deleted groups. +%% Each group is removed from the database.. +%% +%% @spec manage_deleted_groups(Groups) -> void() +%% @end +%%-------------------------------------------------------------------- manage_deleted_groups(Groups) -> mnesia:activity( transaction, @@ -204,6 +223,15 @@ manage_deleted_groups(Groups) -> end, [], Groups) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the existing groups. +%% Each group in the database is updated. +%% +%% @spec manage_existing_groups(Groups) -> void() +%% @end +%%-------------------------------------------------------------------- manage_existing_groups(Groups) -> mnesia:activity( transaction, @@ -213,6 +241,15 @@ manage_existing_groups(Groups) -> end, [], Groups) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the new groups. +%% Each group is inserted in the database. +%% +%% @spec manage_new_groups(Groups) -> void() +%% @end +%%-------------------------------------------------------------------- manage_new_groups(Groups) -> mnesia:activity( transaction, @@ -222,6 +259,14 @@ manage_new_groups(Groups) -> end, [], Groups) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Get all the groups in the database. +%% +%% @spec list_groups() -> Groups +%% @end +%%-------------------------------------------------------------------- list_groups() -> mnesia:activity( transaction, @@ -232,8 +277,17 @@ list_groups() -> end, [], log_monitor_group) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Compare the old and new logfiles. +%% +%% @spec compare_logfiles(Logfiles) -> +%% [{deleted, D}, {existing, E}, {new, N}] +%% @end +%%-------------------------------------------------------------------- compare_logfiles(Logfiles) -> - Old= list_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), @@ -243,6 +297,15 @@ compare_logfiles(Logfiles) -> {new, New} ]. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the deleted logfiles. +%% Stop the monitoring and remove them from the database. +%% +%% @spec manage_deleted_logfiles(Logfiles, Statuses) -> void() +%% @end +%%-------------------------------------------------------------------- manage_deleted_logfiles(Logfiles, Statuses) -> mnesia:activity( transaction, @@ -254,6 +317,15 @@ manage_deleted_logfiles(Logfiles, Statuses) -> end, [], Logfiles) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the existing logfiles. +%% If the error regex has been changed, restart the monitoring. +%% +%% @spec manage_existing_logfiles(Logfiles, Statuses) -> void() +%% @end +%%-------------------------------------------------------------------- manage_existing_logfiles(Logfiles, Statuses) -> mnesia:activity( transaction, @@ -268,18 +340,19 @@ manage_existing_logfiles(Logfiles, Statuses) -> logfiles_sup:add_child([File, ErrorRegex]); true -> ok - end, - 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), - ets:insert(Statuses, {File, inactive}), - logfiles_sup:add_child([File, ErrorRegex]) - end + end end, [], Logfiles) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Manage the new logfiles. +%% Each file is saved to the database and starts being monitored. +%% +%% @spec manage_new_logfiles(Logfiles, Statuses) -> void() +%% @end +%%-------------------------------------------------------------------- manage_new_logfiles(Logfiles, Statuses) -> mnesia:activity( transaction, @@ -291,6 +364,14 @@ manage_new_logfiles(Logfiles, Statuses) -> end, [], Logfiles) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Get all the logfiles in the database. +%% +%% @spec list_logfiles() -> Logfiles +%% @end +%%-------------------------------------------------------------------- list_logfiles() -> mnesia:activity( transaction, diff --git a/apps/log_monitor/src/gatherer.erl b/apps/log_monitor/src/gatherer.erl index 60a8342..8cebf0e 100644 --- a/apps/log_monitor/src/gatherer.erl +++ b/apps/log_monitor/src/gatherer.erl @@ -214,6 +214,15 @@ code_change(_OldVsn, StateName, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Check if the error regex match the text. +%% +%% @spec is_error(Text, ErrorRegex) -> boolean() +%% @end +%%-------------------------------------------------------------------- is_error(Text, ErrorRegex) -> case re:run(Text, ErrorRegex) of {match, _} -> @@ -222,14 +231,39 @@ is_error(Text, ErrorRegex) -> false end. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Get the time (in milliseconds) to gather successive log lines +%% to append to the error line. +%% +%% @spec gathering_time() -> integer() +%% @end +%%-------------------------------------------------------------------- gathering_time() -> {ok, GeneralConfig} = application:get_env(log_monitor, general), proplists:get_value(gathering_time, GeneralConfig). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Get the maximum allowed gathering time (in milliseconds) +%% +%% @spec gathering_time() -> integer() +%% @end +%%-------------------------------------------------------------------- max_gathering_time() -> {ok, GeneralConfig} = application:get_env(log_monitor, general), proplists:get_value(max_gathering_time, GeneralConfig). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Transform the tuple in milliseconds. +%% +%% @spec to_milliseconds({Me, S, Mu}) -> integer() +%% @end +%%-------------------------------------------------------------------- to_milliseconds({Me, S, Mu}) -> (Me * 1000 * 1000 * 1000) + (S * 1000) + (Mu div 1000). diff --git a/apps/log_monitor/src/mailer.erl b/apps/log_monitor/src/mailer.erl index 446277d..c9b5d31 100644 --- a/apps/log_monitor/src/mailer.erl +++ b/apps/log_monitor/src/mailer.erl @@ -156,6 +156,14 @@ emails_to_send() -> end, [], log_monitor_error) end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Send a list of emails. +%% +%% @spec send_emails(Emails) -> void() +%% @end +%%-------------------------------------------------------------------- send_emails(Emails) -> case Emails of [] -> {ok}; @@ -171,6 +179,14 @@ send_emails(Emails) -> end end. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Send an email. +%% +%% @spec send_email(File, Text) -> void() +%% @end +%%-------------------------------------------------------------------- send_email(File, Text) -> {ok, EmailConfig} = application:get_env(log_monitor, email_config), Sender = proplists:get_value(sender, EmailConfig), @@ -180,8 +196,8 @@ send_email(File, Text) -> GroupSubject -> GroupSubject end, Connection = proplists:get_value(connection, EmailConfig), - try receivers(File) of - GroupReceivers -> + case receivers(File) of + {ok, GroupReceivers} -> Receivers = if GroupReceivers == [] -> [DefaultReceiver]; true -> GroupReceivers @@ -198,12 +214,18 @@ send_email(File, Text) -> [Subject, Sender, File, Text] )}, Connection - ) - catch - error:_ -> - ok + ); + {error, _Reason} -> ok end. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Remove the email with the given id from the database. +%% +%% @spec remove_email(Id) -> void() +%% @end +%%-------------------------------------------------------------------- remove_email(Id) -> mnesia:activity( transaction, @@ -212,6 +234,14 @@ remove_email(Id) -> end), ok. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Retrieve the list of receivers for the given file. +%% +%% @spec receivers(File) -> {ok, Receivers} | {error, Reason} +%% @end +%%-------------------------------------------------------------------- receivers(File) -> mnesia:activity( transaction, @@ -220,13 +250,21 @@ receivers(File) -> [{log_monitor_file, File, _, GroupName}] -> case mnesia:read(log_monitor_group, GroupName) of [Group] -> - Group#log_monitor_group.email_receivers; - _ -> throw(file_group_not_found) + {ok, Group#log_monitor_group.email_receivers}; + _ -> {error, "File group not found"} end; - _ -> throw(file_not_found) + _ -> {error, "File not found"} end end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Retrieve the group raw subject (with placeholdres) from the file. +%% +%% @spec group_subject(File) -> Subject +%% @end +%%-------------------------------------------------------------------- group_subject(File) -> mnesia:activity( transaction, @@ -241,15 +279,39 @@ group_subject(File) -> end end). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Build the email subject replacing the placeholders. +%% +%% @spec email_subject(Text, File, FirstErrorLine) -> Subject +%% @end +%%-------------------------------------------------------------------- email_subject(Text, File, FirstErrorLine) -> Text1 = re:replace(Text, "%f", File, [global, {return, list}]), Text2 = re:replace(Text1, "%F", file_name_from_path(File), [global, {return, list}]), re:replace(Text2, "%l", FirstErrorLine, [global, {return, list}]). +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Extract the basename given the full file path. +%% +%% @spec file_name_from_path(File) -> Basename +%% @end +%%-------------------------------------------------------------------- file_name_from_path(File) -> {match, [_, _, Basename]} = re:run(File, "^(.*\/)?(.*)\\..*$", [{capture, all, list}]), Basename. +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Returns the first line of the given text +%% +%% @spec first_line(Text) -> Line +%% @end +%%-------------------------------------------------------------------- first_line(Text) -> lists:takewhile(fun(X) -> X =/= 10 end, Text). %% 10: newline diff --git a/apps/log_monitor/src/watcher.erl b/apps/log_monitor/src/watcher.erl index dfdcd4c..d381113 100644 --- a/apps/log_monitor/src/watcher.erl +++ b/apps/log_monitor/src/watcher.erl @@ -139,5 +139,14 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Get the Pid of the gatherer related to this watcher. +%% +%% @spec gatherer_pid(SupPid) -> pid() +%% @end +%%-------------------------------------------------------------------- gatherer_pid(SupPid) -> hd([Pid || {Id, Pid, _, _} <- supervisor:which_children(SupPid), Id == gatherer]).