rewrite from lager
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
7.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. -module(eRum_app).
  2. -behaviour(application).
  3. -include("rumCom.hrl").
  4. -include("rumDef.hrl").
  5. -include("eRum.hrl").
  6. -export([
  7. start/2
  8. , stop/1
  9. , doStart/0
  10. , startSink/1
  11. , startSink/2
  12. , startHandler/3
  13. ]).
  14. start(_StartType, _StartArgs) ->
  15. {ok, Pid} = eRum_sup:start_link(),
  16. SavedHandlers = doStart(),
  17. doStartExtraSink(),
  18. doStartTraces(),
  19. ?eRumInit(),
  20. {ok, Pid, SavedHandlers}.
  21. %% 启动默认的接收器(sink)
  22. doStart() ->
  23. %% 尝试起送异步管理者
  24. tryStartAsyncMgr(rumUtil:get_env(asyncThreshold, undefined), rumUtil:get_env(asyncThresholdWindow, undefined), ?RumDefSink),
  25. %%尝试安装killer
  26. tryInstallKiller(rumUtil:get_env(killerHwm, undefined), rumUtil:get_env(killerReTime, undefined), ?RumDefSink),
  27. %%尝试启动各个handler
  28. tryStartHandlers(rumUtil:get_env(handlers, ?RumDefHandler), ?RumDefSink),
  29. %% 尝试替换error logger
  30. SavedHandlers = tryStartErrLoggerHandler(rumUtil:get_env(errLoggerRedirect, true), rumUtil:get_env(errLoggerHwm, 0), rumUtil:get_env(errLoggerWhitelist, [])),
  31. eRum:updateLogevelCfg(?RumDefSink),
  32. SavedHandlers.
  33. startSink(?RumDefSink) -> doStart();
  34. startSink(Sink) ->
  35. AllSinksDef = rumUtil:get_env(extraSinks, []),
  36. SinkValue = lists:keyfind(Sink, 1, AllSinksDef),
  37. SinkOpts = ?IIF(SinkValue == false, [], element(2, SinkValue)),
  38. startSink(Sink, SinkOpts).
  39. startSink(Sink, Opts) ->
  40. rumConfig:initSink(Sink),
  41. ChildId = rumUtil:makeInnerSinkName(Sink),
  42. SinkSpec = #{
  43. id => ChildId,
  44. start => {gen_event, start_link, [{local, Sink}]},
  45. restart => permanent,
  46. shutdown => 5000,
  47. type => worker,
  48. modules => [dynamic]},
  49. _ = supervisor:start_child(eRum_sup, SinkSpec),
  50. tryStartAsyncMgr(proplists:get_value(asyncThreshold, Opts, undefined), proplists:get_value(asyncThresholdWindow, Opts, undefined), Sink),
  51. tryInstallKiller(proplists:get_value(killerHwm, Opts, undefined), proplists:get_value(killerReTime, Opts, undefined), Sink),
  52. tryStartHandlers(proplists:get_value(handlers, Opts, []), Sink),
  53. eRum:updateLogevelCfg(Sink).
  54. doStartExtraSink() ->
  55. doStartExtraSinks(rumUtil:get_env(extraSinks, [])).
  56. doStartExtraSinks(Sinks) ->
  57. [startSink(Sink, Opts) || {Sink, Opts} <- Sinks],
  58. ok.
  59. doStartTraces() ->
  60. _ = rumUtil:trace_filter(none),
  61. ok = addTraces().
  62. addTraces() ->
  63. Traces = rumUtil:get_env(traces, []),
  64. [startTrace(One) || One <- Traces],
  65. ok.
  66. startTrace({Handler, Filter}) ->
  67. {ok, _} = eRum:trace(Handler, Filter);
  68. startTrace({Handler, Filter, Level}) when is_atom(Level) ->
  69. {ok, _} = eRum:trace(Handler, Filter, Level).
  70. stop(Handlers) ->
  71. [error_logger:add_report_handler(Handler) || Handler <- Handlers],
  72. rumConfig:cleanup().
  73. tryStartAsyncMgr(undefined, _Window, _Sink) ->
  74. ignore;
  75. tryStartAsyncMgr(Threshold, Window, Sink) ->
  76. case Window of
  77. undefined ->
  78. supervisor:start_child(rumHWatcherSup, [Sink, rumBkdThrottle, [Threshold, erlang:trunc(Threshold * 0.2)]]);
  79. _ ->
  80. supervisor:start_child(rumHWatcherSup, [Sink, rumBkdThrottle, [Threshold, Window]])
  81. end,
  82. ok.
  83. tryInstallKiller(undefined, _ReTime, _Sink) -> ok;
  84. tryInstallKiller(HWM, ReTime, Sink) ->
  85. case ReTime of
  86. undefined ->
  87. _ = supervisor:start_child(rumHWatcherSup, [Sink, rumMgrKiller, [HWM, 5000]]);
  88. _ ->
  89. _ = supervisor:start_child(rumHWatcherSup, [Sink, rumMgrKiller, [HWM, ReTime]])
  90. end,
  91. ok.
  92. tryStartHandlers(undefined, _Sink) -> ok;
  93. tryStartHandlers(Handlers, Sink) ->
  94. %% 启动失败的处理程序将在handler_watcher中处理
  95. NewHandler = doStartHandlers(Handlers, Sink, [], []),
  96. rumConfig:global_set(handlers, rumConfig:global_get(handlers, []) ++ NewHandler),
  97. ok.
  98. doStartHandlers([], _Sink, _NameAcc, HandlerAcc) ->
  99. HandlerAcc;
  100. doStartHandlers([OneHandler | Handlers], Sink, NameAcc, HandlerAcc) ->
  101. {Module, Options} = parseHandlers(OneHandler),
  102. NewNameAcc =
  103. case Module of
  104. {rumBkFile, F} ->
  105. case lists:member(F, NameAcc) of
  106. true ->
  107. error_logger:error_msg("Cannot have same file (~p) in multiple file backends~n", [F]),
  108. throw({error, bad_config});
  109. _ ->
  110. [F | NameAcc]
  111. end;
  112. _ ->
  113. NameAcc
  114. end,
  115. HandlerRet = startHandler(Sink, Module, Options),
  116. doStartHandlers(Handlers, Sink, NewNameAcc, [HandlerRet | HandlerAcc]).
  117. startHandler(Sink, Module, Config) ->
  118. {ok, Watcher} = supervisor:start_child(rumHWatcherSup, [Sink, Module, Config]),
  119. {Module, Watcher, Sink}.
  120. -spec tryStartErrLoggerHandler(boolean(), pos_integer(), list()) -> list().
  121. tryStartErrLoggerHandler(false, _HWM, _Whitelist) -> [];
  122. tryStartErrLoggerHandler(_ErrLoggerRedirect, HWM, WhiteList) ->
  123. case whereis(error_logger) of
  124. undefined ->
  125. %% 在OTP 21及以上版本中,error_logger已弃用,而改用 'logger'
  126. %% 作为一个修补, 启动error_logger并将其安装为 logger handler
  127. %% 我们不能使用 error_logger:add_report_handler 因为我们想要监视这个handler
  128. %% 因此,我们必须手动添加这个 logger handler
  129. %%
  130. %% 从长远来看,我们应该安装一个日志处理程序, but this will bridge the gap for now.
  131. _ = error_logger:start(),
  132. _ = logger:add_handler(error_logger, error_logger, #{level => info, filter_default => log}),
  133. ok = tryRemoveLoggerHandler();
  134. _ ->
  135. ok
  136. end,
  137. %% capture which handlers we removed from error_logger so we can restore them when lager stops
  138. %% 捕获从error_logger中删除的处理程序,以便在lager停止时恢复它们
  139. OldHandlers =
  140. case supervisor:start_child(rumHWatcherSup, [error_logger, rumErrLoggerH, [HWM, rumUtil:get_env(errLoggerGroupLeaderStrategy, handle)]]) of
  141. {ok, _} ->
  142. [begin error_logger:delete_report_handler(X), X end || X <- gen_event:which_handlers(error_logger) -- [rumErrLoggerH | WhiteList]];
  143. {error, _} ->
  144. []
  145. end,
  146. OldHandlers.
  147. %% 在OTP 21.1及更高版本上,我们需要删除`default' handler。但是它可能不存在,因此我们将其包装在try-catch块中
  148. tryRemoveLoggerHandler() ->
  149. try
  150. ok = logger:remove_handler(default)
  151. catch
  152. error:undef -> ok;
  153. Err:Reason ->
  154. error_logger:error_msg("calling logger:remove_handler(default) failed: ~p ~p", [Err, Reason])
  155. end.
  156. parseHandlers([]) ->
  157. [];
  158. parseHandlers({rumBkdFile, Config}) ->
  159. %% this is definitely a new-style config, no expansion needed
  160. maybe_make_handler_id(rumBkdFile, Config);
  161. parseHandlers({Mod, Config}) ->
  162. maybe_make_handler_id(Mod, Config).
  163. maybe_make_handler_id(Mod, Config) ->
  164. %% Allow the backend to generate a gen_event handler id, if it wants to.
  165. %% We don't use erlang:function_exported here because that requires the module
  166. %% already be loaded, which is unlikely at this phase of startup. Using code:load
  167. %% caused undesirable side-effects with generating code-coverage reports.
  168. %%允许后端生成gen_event处理程序id,如果它愿意的话。
  169. %%这里我们没有使用erlang:function_exported,因为这需要用到模块
  170. %%已经加载,这在启动阶段是不太可能的。使用代码:负载
  171. %%会在生成代码覆盖率报告时产生不良的副作用。
  172. try Mod:configToId(Config) of
  173. Id ->
  174. {Id, Config}
  175. catch
  176. error:undef ->
  177. {Mod, Config}
  178. end.