Current section
Files
Jump to
Current section
Files
include/traces_for_apps.hrl
% Copyright (C) 2003-2020 Olivier Boudeville
%
% This file is part of the Ceylan-Traces library.
%
% This library is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License or
% the GNU General Public License, as they are published by the Free Software
% Foundation, either version 3 of these Licenses, or (at your option)
% any later version.
% You can also redistribute it and/or modify it under the terms of the
% Mozilla Public License, version 1.1 or later.
%
% This library is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU Lesser General Public License and the GNU General Public License
% for more details.
%
% You should have received a copy of the GNU Lesser General Public
% License, of the GNU General Public License and of the Mozilla Public License
% along with this library.
% If not, see <http://www.gnu.org/licenses/> and
% <http://www.mozilla.org/MPL/>.
%
% Author: Olivier Boudeville [olivier (dot) boudeville (at) esperide (dot) com]
% Creation date: Tuesday, January 11, 2011
% Defines some macros and functions useful for trace-using applications.
% This is thus the main/only header file such applications should include.
% We have kept macros for all the traces (including the ones for applications,
% and start/stop) for the sake of consistency. Moreover doing so allows to
% communicate more easily with agents like the trace aggregator (as we can then
% share discreetly variables like TraceAggregatorPid).
% Defines everything regarding application traces:
-include("traces_app_header.hrl").
% For exec/0 export:
-include("app_facilities.hrl").
% To avoid warnings if not used:
-export([ app_receive/0, app_receive/1, app_failed/1, app_failed/2 ]).
% For notify_* and al:
-include("traces.hrl").
% Start/stop section.
%
% Any application that is not using (directly on not) traces_for_apps:app_start/2
% (like with the macros below) should then execute by itself:
%
% erlang:process_flag( trap_exit, false )
%
% otherwise the application will silently trap EXIT signals, typically resulting in
% having linked instances failing without notice.
%
% See the comment of traces_for_apps:app_start/2 for more details.
-ifdef(tracing_activated).
% TraceAggregatorPid voluntarily exported from app_start, for app_stop:
-define( app_start,
% true is for InitTraceSupervisor (not even binding a mute variable for
% that)
TraceAggregatorPid = traces_for_apps:app_start( ?MODULE, true )
).
-define( app_stop,
traces_for_apps:app_stop( ?MODULE, TraceAggregatorPid )
).
-define( app_stop_without_waiting_for_trace_supervisor,
traces_for_apps:app_immediate_stop( ?MODULE, TraceAggregatorPid ) ).
-else. % tracing_activated
% Here, even if the trace sending is deactivated, a trace aggregator is created,
% as some processes nevertheless expect to find one at start-up, or some of them
% may have been recompiled to be trace-enabled.
%
% However no trace supervisor is needed here.
%
-define( app_start,
% false is for InitTraceSupervisor (not even binding a mute variable
% for that)
TraceAggregatorPid = traces_for_apps:app_start( ?MODULE, false ) ).
-define( app_stop,
% No supervisor to wait for, here:
traces_for_apps:app_immediate_stop( ?MODULE, TraceAggregatorPid ) ).
-define( app_stop_without_waiting_for_trace_supervisor,
traces_for_apps:app_immediate_stop( ?MODULE, TraceAggregatorPid ) ).
-endif. % tracing_activated
%%%%%%%%%%%%%%%%%%%%%%%%% Between header and footer %%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Defines everything regarding application traces:
-include("traces_app_footer.hrl").
% Helper macro for those who would not know they could have called the
% corresponding function directly:
-define( app_receive, app_receive() ).
% Helper function to write receive clauses in applications which cannot
% interfere with trace supervision, as an application may also receive trace
% control message the application code should remain unware of.
%
% Returns the received value.
%
% Ex: Pid ! { getBaz, [], self() }, MyBaz = app_receive(), ...
%
% to be used instead of:
%
% Pid ! { getBaz, [], self() },
% receive
%
% { wooper_result, V } ->
% V
%
% end,
% ...
%
-spec app_receive() -> any().
app_receive() ->
traces:receive_applicative_message().
% Helper function to write receive clauses for specific messages in applications
% while not interfering with trace supervision.
%
-spec app_receive( any() ) -> void().
app_receive( Message ) ->
traces:receive_applicative_message( Message ).
% Helper macro for those who would not know they could have called the
% corresponding function directly:
%
-define( app_failed, app_failed() ).
% Handles an application failure.
%
-spec app_failed( text_utils:ustring() ) -> no_return().
app_failed( Reason ) ->
% For some reason erlang:error is unable to interpret strings as strings,
% they are always output as unreadable lists.
Message = text_utils:format( "Application ~s failed, reason: ~s.",
[ ?MODULE, Reason ] ),
trace_utils:error( Message ),
?app_fatal( Message ),
% Needed, otherwise error_logger may not display anything:
system_utils:await_output_completion(),
erlang:error( "Application ~s failed.", [ ?MODULE ] ).
% Handles an application failure, using specified first string as an advertised
% reason with format characters (ex: '~w') and specified list as actual values
% to be formatted.
%
-spec app_failed( text_utils:format_string(), text_utils:format_values() ) ->
no_return().
app_failed( FormatReason, FormatValues ) ->
app_failed( text_utils:format( FormatReason, FormatValues ) ).