|
|
@ -8,6 +8,7 @@ |
|
|
|
start/0 |
|
|
|
, start/2 |
|
|
|
, stop/1 |
|
|
|
, doStart/0 |
|
|
|
, doStart/1 |
|
|
|
, startHandler/3 |
|
|
|
, configure_sink/2 |
|
|
@ -20,24 +21,25 @@ start() -> |
|
|
|
|
|
|
|
start(_StartType, _StartArgs) -> |
|
|
|
{ok, Pid} = eRum_sup:start_link(), |
|
|
|
SavedHandlers = boot(), |
|
|
|
SavedHandlers = doStart(), |
|
|
|
_ = doStart('__all_extra'), |
|
|
|
_ = doStart('__traces'), |
|
|
|
clean_up_config_checks(), |
|
|
|
{ok, Pid, SavedHandlers}. |
|
|
|
|
|
|
|
boot() -> |
|
|
|
%% Handle the default sink. |
|
|
|
%% 启动默认的接收器(sink) |
|
|
|
doStart() -> |
|
|
|
%% 尝试起送异步管理者 |
|
|
|
tryStartAsyncMgr(rumUtil:get_env(asyncThreshold, undefined), rumUtil:get_env(asyncThresholdWindow, undefined), ?RumDefSink), |
|
|
|
|
|
|
|
%%尝试安装killer |
|
|
|
tryInstallKiller(rumUtil:get_env(killerHwm, undefined), rumUtil:get_env(killerReTime, undefined), ?RumDefSink), |
|
|
|
|
|
|
|
%%尝试启动各个handler |
|
|
|
tryStartHandlers(rumUtil:get_env(handlers, ?RumDefHandler), ?RumDefSink), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SavedHandlers = start_error_logger_handler(rumUtil:get_env(error_logger_redirect, true), rumUtil:get_env(error_logger_hwm, 0), rumUtil:get_env(error_logger_whitelist, [])), |
|
|
|
eRum:update_loglevel_config(?RumDefSink), |
|
|
|
%% 尝试替换error logger |
|
|
|
SavedHandlers = tryStartErrLoggerHandler(rumUtil:get_env(errLoggerRedirect, true), rumUtil:get_env(errLoggerHwm, 0), rumUtil:get_env(errLoggerWhitelist, [])), |
|
|
|
eRum:updateLogevelCfg(?RumDefSink), |
|
|
|
SavedHandlers. |
|
|
|
|
|
|
|
doStart('__traces') -> |
|
|
@ -45,11 +47,11 @@ doStart('__traces') -> |
|
|
|
ok = add_configured_traces(); |
|
|
|
|
|
|
|
doStart('__all_extra') -> |
|
|
|
configure_extra_sinks(application:get_env(lager, extra_sinks, [])); |
|
|
|
doStartExtraSinks(rumUtil:get_env(extra_sinks, [])); |
|
|
|
|
|
|
|
doStart(?RumDefSink) -> boot(); |
|
|
|
doStart(?RumDefSink) -> doStart(); |
|
|
|
doStart(Sink) -> |
|
|
|
AllSinksDef = application:get_env(lager, extra_sinks, []), |
|
|
|
AllSinksDef = rumUtil:get_env(extra_sinks, []), |
|
|
|
boot_sink(Sink, lists:keyfind(Sink, 1, AllSinksDef)). |
|
|
|
|
|
|
|
boot_sink(Sink, {Sink, Def}) -> |
|
|
@ -95,19 +97,18 @@ doStartHandlers([], _Sink, _NameAcc, HandlerAcc) -> |
|
|
|
HandlerAcc; |
|
|
|
doStartHandlers([OneHandler | Handlers], Sink, NameAcc, HandlerAcc) -> |
|
|
|
{Module, Options} = expand_handlers(OneHandler), |
|
|
|
NewNameAcc = |
|
|
|
case Module of |
|
|
|
{rumBackendFile, F} -> |
|
|
|
case lists:member(F, NameAcc) of |
|
|
|
true -> |
|
|
|
error_logger:error_msg("Cannot have same file (~p) in multiple file backends~n", [F]), |
|
|
|
throw({error, bad_config}); |
|
|
|
_ -> |
|
|
|
[F | NameAcc] |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
NameAcc |
|
|
|
end, |
|
|
|
case Module of |
|
|
|
{rumBackendFile, F} -> |
|
|
|
case lists:member(F, NameAcc) of |
|
|
|
true -> |
|
|
|
error_logger:error_msg("Cannot have same file (~p) in multiple file backends~n", [F]), |
|
|
|
throw({error, bad_config}); |
|
|
|
_ -> |
|
|
|
NewNameAcc = [F | NameAcc] |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
NewNameAcc = NameAcc |
|
|
|
end, |
|
|
|
|
|
|
|
HandlerRet = startHandler(Sink, Module, Options), |
|
|
|
doStartHandlers(Handlers, Sink, NewNameAcc, [HandlerRet | HandlerAcc]). |
|
|
@ -116,87 +117,59 @@ startHandler(Sink, Module, Config) -> |
|
|
|
{ok, Watcher} = supervisor:start_child(rumHWatcherSup, [Sink, Module, Config]), |
|
|
|
{Module, Watcher, Sink}. |
|
|
|
|
|
|
|
interpret_hwm(undefined) -> |
|
|
|
undefined; |
|
|
|
interpret_hwm(HWM) when not is_integer(HWM) orelse HWM < 0 -> |
|
|
|
_ = eRum:log(warning, self(), "Invalid error_logger high water mark: ~p, disabling", [HWM]), |
|
|
|
undefined; |
|
|
|
interpret_hwm(HWM) -> |
|
|
|
HWM. |
|
|
|
|
|
|
|
-spec start_error_logger_handler(boolean(), pos_integer(), list()) -> list(). |
|
|
|
start_error_logger_handler(false, _HWM, _Whitelist) -> |
|
|
|
[]; |
|
|
|
start_error_logger_handler(true, HWM, WhiteList) -> |
|
|
|
GlStrategy = |
|
|
|
case application:get_env(lager, error_logger_groupleader_strategy) of |
|
|
|
undefined -> |
|
|
|
handle; |
|
|
|
{ok, GlStrategy0} when |
|
|
|
GlStrategy0 =:= handle; |
|
|
|
GlStrategy0 =:= ignore; |
|
|
|
GlStrategy0 =:= mirror -> |
|
|
|
GlStrategy0; |
|
|
|
{ok, BadGlStrategy} -> |
|
|
|
error_logger:error_msg( |
|
|
|
"Invalid value for 'error_logger_groupleader_strategy': ~p~n", |
|
|
|
[BadGlStrategy]), |
|
|
|
throw({error, bad_config}) |
|
|
|
end, |
|
|
|
|
|
|
|
-spec tryStartErrLoggerHandler(boolean(), pos_integer(), list()) -> list(). |
|
|
|
tryStartErrLoggerHandler(false, _HWM, _Whitelist) -> []; |
|
|
|
tryStartErrLoggerHandler(_ErrLoggerRedirect, HWM, WhiteList) -> |
|
|
|
case whereis(error_logger) of |
|
|
|
undefined -> |
|
|
|
%% On OTP 21 and above, error_logger is deprecated in favor of 'logger' |
|
|
|
%% As a band-aid, boot up error_logger anyway and install it as a logger handler |
|
|
|
%% we can't use error_logger:add_report_handler because we want supervision of the handler |
|
|
|
%% so we have to manually add the logger handler |
|
|
|
%% 在OTP 21及以上版本中,error_logger已弃用,而改用 'logger' |
|
|
|
%% 作为一个修补, 启动error_logger并将其安装为 logger handler |
|
|
|
%% 我们不能使用 error_logger:add_report_handler 因为我们想要监视这个handler |
|
|
|
%% 因此,我们必须手动添加这个 logger handler |
|
|
|
%% |
|
|
|
%% Longer term we should be installing a logger handler instead, but this will bridge the gap |
|
|
|
%% for now. |
|
|
|
%% 从长远来看,我们应该安装一个日志处理程序, but this will bridge the gap for now. |
|
|
|
_ = error_logger:start(), |
|
|
|
_ = logger:add_handler(error_logger, error_logger, #{level => info, filter_default => log}), |
|
|
|
ok = maybe_remove_logger_handler(); |
|
|
|
ok = tryRemoveLoggerHandler(); |
|
|
|
_ -> |
|
|
|
ok |
|
|
|
end, |
|
|
|
|
|
|
|
%% capture which handlers we removed from error_logger so we can restore them when lager stops |
|
|
|
%% 捕获从error_logger中删除的处理程序,以便在lager停止时恢复它们 |
|
|
|
OldHandlers = |
|
|
|
case supervisor:start_child(lager_handler_watcher_sup, [error_logger, error_logger_lager_h, [HWM, GlStrategy]]) of |
|
|
|
case supervisor:start_child(rumHWatcherSup, [error_logger, rumErrLoggerH, [HWM, rumUtil:get_env(errLoggerGroupLeaderStrategy, handle)]]) of |
|
|
|
{ok, _} -> |
|
|
|
[begin error_logger:delete_report_handler(X), X end || |
|
|
|
X <- gen_event:which_handlers(error_logger) -- [error_logger_lager_h | WhiteList]]; |
|
|
|
[begin error_logger:delete_report_handler(X), X end || X <- gen_event:which_handlers(error_logger) -- [error_logger_lager_h | WhiteList]]; |
|
|
|
{error, _} -> |
|
|
|
[] |
|
|
|
end, |
|
|
|
OldHandlers. |
|
|
|
|
|
|
|
%% On OTP 21.1 and higher we need to remove the `default' handler. |
|
|
|
%% But it might not exist, so we will wrap this in a try-catch |
|
|
|
%% block |
|
|
|
maybe_remove_logger_handler() -> |
|
|
|
%% 在OTP 21.1及更高版本上,我们需要删除`default' handler。但是它可能不存在,因此我们将其包装在try-catch块中 |
|
|
|
tryRemoveLoggerHandler() -> |
|
|
|
try |
|
|
|
ok = logger:remove_handler(default) |
|
|
|
catch |
|
|
|
error:undef -> ok; |
|
|
|
Err:Reason -> |
|
|
|
error_logger:error_msg("calling logger:remove_handler(default) failed: ~p ~p", |
|
|
|
[Err, Reason]) |
|
|
|
error_logger:error_msg("calling logger:remove_handler(default) failed: ~p ~p", [Err, Reason]) |
|
|
|
end. |
|
|
|
|
|
|
|
configure_sink(Sink, SinkDef) -> |
|
|
|
rumConfig:initSink(Sink), |
|
|
|
ChildId = rumUtil:make_internal_sink_name(Sink), |
|
|
|
ChildId = rumUtil:makeInnerSinkName(Sink), |
|
|
|
_ = supervisor:start_child(eRum_sup, {ChildId, {gen_event, start_link, [{local, Sink}]}, permanent, 5000, worker, dynamic}), |
|
|
|
tryStartAsyncMgr(Sink, proplists:get_value(asyncThreshold, SinkDef), proplists:get_value(asyncThresholdWindow, SinkDef)), |
|
|
|
_ = tryInstallKiller(Sink, proplists:get_value(killerHwm, SinkDef), |
|
|
|
proplists:get_value(killerReTime, SinkDef)), |
|
|
|
_ = tryInstallKiller(Sink, proplists:get_value(killerHwm, SinkDef), proplists:get_value(killerReTime, SinkDef)), |
|
|
|
tryStartHandlers(proplists:get_value(handlers, SinkDef, []), Sink), |
|
|
|
eRum:update_loglevel_config(Sink). |
|
|
|
eRum:updateLogevelCfg(Sink). |
|
|
|
|
|
|
|
|
|
|
|
configure_extra_sinks(Sinks) -> |
|
|
|
lists:foreach(fun({Sink, Proplist}) -> configure_sink(Sink, Proplist) end, Sinks). |
|
|
|
doStartExtraSinks(Sinks) -> |
|
|
|
[configure_sink(Sink, Opts) || {Sink, Opts} <- Sinks], |
|
|
|
ok. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|