|
-include("rumCom.hrl").
|
|
%% 应用名字
|
|
-define(RumAppName, eRum).
|
|
|
|
%% 三元表达式
|
|
-define(IIF(Cond, Ret1, Ret2), (case Cond of true -> Ret1; _ -> Ret2 end)).
|
|
|
|
%% 错误日志宏定义
|
|
-define(ERR(Format), error_logger:error_msg(Format)).
|
|
-define(ERR(Format, Args), error_logger:error_msg(Format, Args)).
|
|
|
|
-define(Print(Args), io:format("IMY************~p~n", [Args])).
|
|
|
|
%% 额外进程字典key
|
|
-define(PdMdKey, pdRumMd).
|
|
-define(RumTrackSink, '__trace_sink').
|
|
|
|
%% 旋转日志超时时间
|
|
-define(RumRotateTimeout, 100000).
|
|
|
|
%% 部分默认配置值
|
|
-define(RumDefTracer, lager_default_tracer).
|
|
-define(RumErrLogSink, error_logger_lager_event).
|
|
|
|
%% rumBkdConsole的选项
|
|
-type rumConsoleOpt() ::
|
|
{id, atom() | {atom(), atom()}} |
|
|
{use_stderr, boolean()} |
|
|
{group_leader, false | pid() | atom()} |
|
|
{formatter, atom()} |
|
|
{formatter_config, list()}.
|
|
|
|
%% rumBkdFile的选项
|
|
-type rumFileOpt() ::
|
|
{file, binary()} |
|
|
{level, rumAtomLevel() | atom()} |
|
|
{size, non_neg_integer()} |
|
|
{date, string()} |
|
|
{count, non_neg_integer()} |
|
|
{rotator, atom()} |
|
|
{high_water_mark, non_neg_integer()} |
|
|
%% 对于特定的接收器事件队列刷新,请使用改选项
|
|
{flush_queue, boolean()} |
|
|
%% 对于接收器 如果flush_queue为true,则可以设置消息队列长度阈值,在该阈值处将开始丢弃消息。默认阈值为0,
|
|
%% 这意味着如果flush_queue为true,则超过高水位标记时将丢弃消息,而不管消息队列的长度如何。:
|
|
{flush_threshold, non_neg_integer()} |
|
|
{sync_interval, non_neg_integer()} |
|
|
{sync_size, non_neg_integer()} |
|
|
{sync_on, rumAtomLevel()} |
|
|
{check_interval, non_neg_integer()} |
|
|
{formatter, atom()} |
|
|
{formatter_config, term()}.
|
|
|
|
%% BkdFile选项默认值
|
|
-define(RumDefLogLevel, info).
|
|
-define(RumDefRotateSize, 10485760). %% 10mb
|
|
-define(RumDefRotateDate, "$D0"). %% midnight
|
|
-define(RumDefRotateCnt, 5).
|
|
-define(RumDefRotateMod, rumRotatorIns).
|
|
-define(RumDefSyncLevel, error).
|
|
-define(RumDefSyncInterval, 1000).
|
|
-define(RumDefSyncSize, 1024 * 64). %% 64kb
|
|
-define(RumDefCheckInterval, 1000).
|
|
-define(RumDefCheckHWM, 1000). %% IMY-todo修正该默认值
|
|
-define(RumDefFlushQueue, true).
|
|
-define(RumDefFlushThreshold, 0). %% IMY-todo修正该默认值
|
|
-define(RumDefFormatter, rumFormatter).
|
|
-define(RumDefFormatterCfg, []).
|
|
|
|
%% 默认日志文件选项
|
|
-define(RumDefHandler,
|
|
[
|
|
{rumBkdConsole, [{level, info}]},
|
|
{rumBkdFile, [{file, <<"./log/error.log">>}, {level, '>=error'}, {size, 10485760}, {date, "$D0"}, {count, 5}]},
|
|
{rumBkdFile, [{file, <<"./log/console.log">>}, {level, '>=debug'}, {size, 10485760}, {date, "$D0"}, {count, 5}]}
|
|
]).
|
|
|
|
-record(rumShaper, {
|
|
id :: any()
|
|
%% 每秒我们尝试传递多少消息
|
|
, hwm = undefined :: 'undefined' | pos_integer()
|
|
%% 这秒内我们收到了多少条消息
|
|
, mps = 0 :: non_neg_integer()
|
|
%% 当前秒
|
|
, lastTime = rumTime:now() :: erlang:timestamp()
|
|
%% 此秒内丢弃的消息数
|
|
, dropped = 0 :: non_neg_integer()
|
|
%% If true, flush notify messages from msg queue at overload
|
|
%% 如果为true,则在过载时刷新来自消息队列的通知消息
|
|
, flushQueue = true :: boolean()
|
|
, flushThreshold = 0 :: integer()
|
|
%% timer
|
|
, timer = make_ref() :: reference()
|
|
%% optional filter fun to avoid counting suppressed messages against HWM totals
|
|
%% 可选的过滤器函数,以避免对HWM总数计算抑制消息
|
|
, filter = fun(_) -> false end :: fun()
|
|
}).
|
|
|
|
-type rumShaper() :: #rumShaper{}.
|
|
|
|
-type rumAtomLevel() :: none | debug | info | notice | warning | error | critical | alert | emergency.
|
|
-type rumMaskLevel() :: 0..256.
|
|
|
|
|
|
%% 日志等级列表
|
|
-define(RumLevels, [debug, info, notice, warning, error, critical, alert, emergency, none]).
|
|
|
|
%% 使用这些“功能”意味着,出于安全考虑,参数列表不会被截断
|
|
-define(RumLevelsUnsafe, [{debug_unsafe, debug}, {info_unsafe, info}, {notice_unsafe, notice}, {warning_unsafe, warning}, {error_unsafe, error}, {critical_unsafe, critical}, {alert_unsafe, alert}, {emergency_unsafe, emergency}]).
|
|
|
|
|
|
-define(RunShouldLog(Sink, Level), (rumUtil:levelToNum(Level) band element(1, rumConfig:get({Sink, loglevel}, {?none, []}))) /= 0).
|
|
|
|
-define(RunShouldLog(Level), (rumUtil:levelToNum(Level) band element(1, rumConfig:get(loglevel, {?none, []}))) /= 0).
|
|
|
|
-define(RunNotify(Level, Pid, Format, Args),
|
|
gen_emm:info_notify(rumEvent, {mWriteLog, rumMsg:new(io_lib:format(Format, Args), Level, [{pid, Pid}, {line, ?LINE}, {file, ?FILE}, {module, ?MODULE}], [])})).
|
|
|
|
%%仅供内部使用仅内部非阻塞日志记录调用,当我们仍在启动大型啤酒时尝试进行日志记录(通常为错误)时,会有一些特殊处理。
|
|
-ifdef(TEST).
|
|
-define(INT_LOG(Level, Format, Args),
|
|
case ?RunShouldLog(Level) of
|
|
true ->
|
|
?RunNotify(Level, self(), Format, Args);
|
|
_ ->
|
|
ok
|
|
end).
|
|
-else.
|
|
-define(INT_LOG(Level, Format, Args),
|
|
Self = self(),
|
|
%%在生成中执行此操作,这样就不会导致从gen_event处理程序调用gen_event:which_handlers的死锁
|
|
spawn(fun() ->
|
|
case catch (gen_event:which_handlers(rumEvent)) of
|
|
X when X == []; X == {'EXIT', noproc}; X == [rumBkdThrottle] ->
|
|
%% there's no handlers yet or lager isn't running, try again
|
|
%% in half a second.
|
|
timer:sleep(500),
|
|
?RunNotify(Level, Self, Format, Args);
|
|
_ ->
|
|
case ?RunShouldLog(Level) of
|
|
true ->
|
|
?RunNotify(Level, Self, Format, Args);
|
|
_ ->
|
|
ok
|
|
end
|
|
end
|
|
end)).
|
|
-endif.
|
|
|
|
|
|
|