%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1996-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% -module(sasl). %% External exports -export([start/2, stop/1]). %% Internal exports -export([init/1, pred/1]). %%%----------------------------------------------------------------- %%% This module implements the application SASL, %%% and a supervisor for SASL. %%%----------------------------------------------------------------- -behaviour(application). -record(state, {sasl_error_logger, error_logger_mf}). start(_, []) -> Handler = get_sasl_error_logger(), Type = get_sasl_error_logger_type(), Mf = get_error_logger_mf(), add_sasl_error_logger(Handler, Type), add_error_logger_mf(Mf), State = #state{sasl_error_logger = Handler, error_logger_mf = Mf}, case supervisor:start_link({local, sasl_sup}, sasl, []) of {ok, Pid} -> {ok, Pid, State}; Error -> Error end. stop(State) -> delete_sasl_error_logger(State#state.sasl_error_logger), delete_error_logger_mf(State#state.error_logger_mf). %%----------------------------------------------------------------- %% Internal functions %%----------------------------------------------------------------- get_sasl_error_logger() -> case application:get_env(sasl, sasl_error_logger) of {ok, false} -> undefined; {ok, tty} -> tty; {ok, {file, File}} when is_list(File) -> {file, File}; {ok, Bad} -> exit({bad_config, {sasl, {sasl_error_logger, Bad}}}); _ -> undefined end. get_sasl_error_logger_type() -> case application:get_env(sasl, errlog_type) of {ok, error} -> error; {ok, progress} -> progress; {ok, all} -> all; {ok, Bad} -> exit({bad_config, {sasl, {errlog_type, Bad}}}); _ -> all end. get_error_logger_mf() -> case catch get_mf() of {'EXIT', Reason} -> exit(Reason); Mf -> Mf end. get_mf() -> Dir = get_mf_dir(), MaxB = get_mf_maxb(), MaxF = get_mf_maxf(), case {Dir, MaxB, MaxF} of {undefined,undefined,undefined} -> undefined; {undefined,_,_} -> exit({missing_config, {sasl, error_logger_mf_dir}}); {_,undefined,_} -> exit({missing_config, {sasl, error_logger_mf_maxbytes}}); {_,_,undefined} -> exit({missing_config, {sasl, error_logger_mf_maxfiles}}); R -> R end. get_mf_dir() -> case application:get_env(sasl, error_logger_mf_dir) of {ok, false} -> undefined; {ok, Dir} when is_list(Dir) -> Dir; undefined -> undefined; {ok, Bad} -> exit({bad_config, {sasl, {error_logger_mf_dir, Bad}}}) end. get_mf_maxb() -> case application:get_env(sasl, error_logger_mf_maxbytes) of {ok, MaxB} when is_integer(MaxB) -> MaxB; undefined -> undefined; {ok, Bad} -> exit({bad_config, {sasl, {error_logger_mf_maxbytes, Bad}}}) end. get_mf_maxf() -> case application:get_env(sasl, error_logger_mf_maxfiles) of {ok, MaxF} when is_integer(MaxF), MaxF > 0, MaxF < 256 -> MaxF; undefined -> undefined; {ok, Bad} -> exit({bad_config, {sasl, {error_logger_mf_maxfiles, Bad}}}) end. add_sasl_error_logger(undefined, _Type) -> ok; add_sasl_error_logger(Handler, Type) -> error_logger:add_report_handler(mod(Handler), args(Handler, Type)). delete_sasl_error_logger(undefined) -> ok; delete_sasl_error_logger(Type) -> error_logger:delete_report_handler(mod(Type)). mod(tty) -> sasl_report_tty_h; mod({file, _File}) -> sasl_report_file_h. args({file, File}, Type) -> {File, type(Type)}; args(_, Type) -> type(Type). type(error) -> error; type(progress) -> progress; type(_) -> all. add_error_logger_mf(undefined) -> ok; add_error_logger_mf({Dir, MaxB, MaxF}) -> error_logger:add_report_handler( log_mf_h, log_mf_h:init(Dir, MaxB, MaxF, fun pred/1)). delete_error_logger_mf(undefined) -> ok; delete_error_logger_mf(_) -> error_logger:delete_report_handler(log_mf_h). pred({_Type, GL, _Msg}) when node(GL) =/= node() -> false; pred(_) -> true. %%%----------------------------------------------------------------- %%% supervisor functionality %%%----------------------------------------------------------------- init([]) -> SupFlags = {one_for_one, 0, 1}, %% Reboot node if release_handler crashes! SafeSupervisor = {sasl_safe_sup, {supervisor, start_link, [{local, sasl_safe_sup}, ?MODULE, safe]}, permanent, infinity, supervisor, [?MODULE]}, ReleaseH = {release_handler, {release_handler, start_link, []}, permanent, 2000, worker, []}, % Note! [] for modules! We % can't change code on r_h % this way!! {ok, {SupFlags, [SafeSupervisor, ReleaseH]}}; init(safe) -> SupFlags = {one_for_one, 4, 3600}, AlarmH = {alarm_handler, {alarm_handler, start_link, []}, permanent, 2000, worker, dynamic}, Overload = {overload, {overload, start_link, []}, permanent, 2000, worker, [overload]}, {ok, {SupFlags, [AlarmH, Overload]}}.