|
@ -14,13 +14,12 @@ |
|
|
, stop/0 |
|
|
, stop/0 |
|
|
|
|
|
|
|
|
%% log and log param |
|
|
%% log and log param |
|
|
, dispatch_log/12 |
|
|
|
|
|
, do_log_impl/13 |
|
|
|
|
|
, safe_format/3 |
|
|
|
|
|
, safe_format_chop/3 |
|
|
|
|
|
, unsafe_format/2 |
|
|
|
|
|
, md/0 |
|
|
|
|
|
, md/1 |
|
|
|
|
|
|
|
|
, dispatchLog/12 |
|
|
|
|
|
, doLogImpl/13 |
|
|
|
|
|
, safeFormat/3 |
|
|
|
|
|
, unsafeFormat/2 |
|
|
|
|
|
, getMd/0 |
|
|
|
|
|
, setMd/1 |
|
|
, getLogLevel/1 |
|
|
, getLogLevel/1 |
|
|
, getLogLevel/2 |
|
|
, getLogLevel/2 |
|
|
, setLogLevel/2 |
|
|
, setLogLevel/2 |
|
@ -31,22 +30,19 @@ |
|
|
, setLogHwm/2 |
|
|
, setLogHwm/2 |
|
|
, setLogHwm/3 |
|
|
, setLogHwm/3 |
|
|
, setLogHwm/4 |
|
|
, setLogHwm/4 |
|
|
, rotate_handler/1 |
|
|
|
|
|
, rotate_handler/2 |
|
|
|
|
|
, rotate_sink/1 |
|
|
|
|
|
, rotate_all/0 |
|
|
|
|
|
, posix_error/1 |
|
|
|
|
|
|
|
|
|
|
|
%% stack |
|
|
|
|
|
, pr/2 |
|
|
|
|
|
, pr/3 |
|
|
|
|
|
, pr_stacktrace/1 |
|
|
|
|
|
, pr_stacktrace/2 |
|
|
|
|
|
|
|
|
, rotateHandler/1 |
|
|
|
|
|
, rotateHandler/2 |
|
|
|
|
|
, rotateSink/1 |
|
|
|
|
|
, rotateAll/0 |
|
|
|
|
|
|
|
|
|
|
|
%% stack parse |
|
|
|
|
|
, parseStack/1 |
|
|
|
|
|
, parseStack/3 |
|
|
|
|
|
|
|
|
%% trace |
|
|
%% trace |
|
|
, trace/2 |
|
|
, trace/2 |
|
|
, trace/3 |
|
|
, trace/3 |
|
|
, trace_file/2 |
|
|
|
|
|
|
|
|
, traceFile/2 |
|
|
, trace_file/3 |
|
|
, trace_file/3 |
|
|
, trace_file/4 |
|
|
, trace_file/4 |
|
|
, trace_console/1 |
|
|
, trace_console/1 |
|
@ -79,27 +75,21 @@ start() -> |
|
|
stop() -> |
|
|
stop() -> |
|
|
application:stop(eRum). |
|
|
application:stop(eRum). |
|
|
|
|
|
|
|
|
-spec dispatch_log(atom(), rumAtomLevel(), pid(), node(), atom(), atom(), integer(), list(), string(), list() | none, pos_integer(), safe | unsafe) -> ok | {error, lager_not_running} | {error, {sink_not_configured, atom()}}. |
|
|
|
|
|
|
|
|
-spec dispatchLog(atom(), rumAtomLevel(), pid(), node(), atom(), atom(), integer(), list(), string(), list() | none, pos_integer(), safe | unsafe) -> ok | {error, lager_not_running} | {error, {sink_not_configured, atom()}}. |
|
|
%% this is the same check that the parse transform bakes into the module at compile time see rumTransform (lines 173-216) |
|
|
%% this is the same check that the parse transform bakes into the module at compile time see rumTransform (lines 173-216) |
|
|
dispatch_log(Sink, Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Size, Safety) -> |
|
|
|
|
|
|
|
|
dispatchLog(Sink, Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Size, Safety) -> |
|
|
case ?eRumCfg:get(Sink) band Severity /= 0 of |
|
|
case ?eRumCfg:get(Sink) band Severity /= 0 of |
|
|
true -> |
|
|
true -> |
|
|
do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety); |
|
|
|
|
|
|
|
|
doLogImpl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety); |
|
|
_ -> |
|
|
_ -> |
|
|
ok |
|
|
ok |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety) -> |
|
|
|
|
|
|
|
|
doLogImpl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety) -> |
|
|
TraceFilters = rumConfig:ptGet({Sink, trace}, []), |
|
|
TraceFilters = rumConfig:ptGet({Sink, trace}, []), |
|
|
{Destinations, TraceSinkPid} = |
|
|
|
|
|
case TraceFilters of |
|
|
|
|
|
[] -> |
|
|
|
|
|
{[], undefined}; |
|
|
|
|
|
_ -> |
|
|
|
|
|
{rumUtil:check_traces(Metadata, Severity, TraceFilters, []), whereis(?RumTrackSink)} |
|
|
|
|
|
end, |
|
|
|
|
|
|
|
|
Destinations = ?IIF(TraceFilters /= [], rumUtil:check_traces(Metadata, Severity, TraceFilters, []), []), |
|
|
|
|
|
|
|
|
MsgStr = ?IIF(Args /= [] andalso Args /= undefined, ?IIF(Safety == safe, eFmt:formatBin(Format, [Args], [{charsLimit, Size}]), eFmt:formatBin(Format, [Args])), Format), |
|
|
|
|
|
|
|
|
MsgStr = ?IIF(Args /= [] andalso Args /= undefined, ?IIF(Safety == safe, safeFormat(Format, [Args], [{charsLimit, Size}]), unsafeFormat(Format, [Args])), Format), |
|
|
NowMs = rumTime:nowMs(), |
|
|
NowMs = rumTime:nowMs(), |
|
|
NowStr = rumUtil:msToBinStr(NowMs), |
|
|
NowStr = rumUtil:msToBinStr(NowMs), |
|
|
RumMsg = #rumMsg{severity = Severity, pid = Pid, node = Node, module = Module, function = Function, line = Line, metadata = Metadata, datetime = NowStr, timestamp = NowMs, message = MsgStr, destinations = Destinations}, |
|
|
RumMsg = #rumMsg{severity = Severity, pid = Pid, node = Node, module = Module, function = Function, line = Line, metadata = Metadata, datetime = NowStr, timestamp = NowMs, message = MsgStr, destinations = Destinations}, |
|
@ -110,16 +100,16 @@ do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, |
|
|
false -> |
|
|
false -> |
|
|
gen_emm:call_notify(Sink, {mWriteLog, RumMsg}) |
|
|
gen_emm:call_notify(Sink, {mWriteLog, RumMsg}) |
|
|
end, |
|
|
end, |
|
|
case TraceSinkPid /= undefined of |
|
|
|
|
|
true -> |
|
|
|
|
|
gen_emm:info_notify(TraceSinkPid, {mWriteLog, RumMsg}); |
|
|
|
|
|
false -> |
|
|
|
|
|
ok |
|
|
|
|
|
|
|
|
case whereis(?RumTrackSink) of |
|
|
|
|
|
undefined -> |
|
|
|
|
|
ok; |
|
|
|
|
|
TraceSinkPid -> |
|
|
|
|
|
gen_emm:info_notify(TraceSinkPid, {mWriteLog, RumMsg}) |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
%% @doc Get lager metadata for current process |
|
|
%% @doc Get lager metadata for current process |
|
|
-spec md() -> [{atom(), any()}]. |
|
|
|
|
|
md() -> |
|
|
|
|
|
|
|
|
-spec getMd() -> [{atom(), any()}]. |
|
|
|
|
|
getMd() -> |
|
|
case erlang:get(?PdMdKey) of |
|
|
case erlang:get(?PdMdKey) of |
|
|
undefined -> []; |
|
|
undefined -> []; |
|
|
MD -> MD |
|
|
MD -> MD |
|
@ -127,8 +117,8 @@ md() -> |
|
|
|
|
|
|
|
|
%% @doc Set lager metadata for current process. |
|
|
%% @doc Set lager metadata for current process. |
|
|
%% Will badarg if you don't supply a list of {key, value} tuples keyed by atoms. |
|
|
%% Will badarg if you don't supply a list of {key, value} tuples keyed by atoms. |
|
|
-spec md([{atom(), any()}, ...]) -> ok. |
|
|
|
|
|
md(NewMD) when is_list(NewMD) -> |
|
|
|
|
|
|
|
|
-spec setMd([{atom(), any()}, ...]) -> ok. |
|
|
|
|
|
setMd(NewMD) when is_list(NewMD) -> |
|
|
%% make sure its actually a real proplist |
|
|
%% make sure its actually a real proplist |
|
|
case lists:all( |
|
|
case lists:all( |
|
|
fun({Key, _Value}) when is_atom(Key) -> true; |
|
|
fun({Key, _Value}) when is_atom(Key) -> true; |
|
@ -137,23 +127,12 @@ md(NewMD) when is_list(NewMD) -> |
|
|
true -> |
|
|
true -> |
|
|
erlang:put(?PdMdKey, NewMD), |
|
|
erlang:put(?PdMdKey, NewMD), |
|
|
ok; |
|
|
ok; |
|
|
false -> |
|
|
|
|
|
|
|
|
_ -> |
|
|
erlang:error(badarg) |
|
|
erlang:error(badarg) |
|
|
end; |
|
|
end; |
|
|
md(_) -> |
|
|
|
|
|
|
|
|
setMd(_) -> |
|
|
erlang:error(badarg). |
|
|
erlang:error(badarg). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
validate_trace_filters(Filters, Level, Backend) -> |
|
|
|
|
|
Sink = proplists:get_value(sink, Filters, ?RumDefSink), |
|
|
|
|
|
{Sink, |
|
|
|
|
|
rumUtil:validate_trace({ |
|
|
|
|
|
proplists:delete(sink, Filters), |
|
|
|
|
|
Level, |
|
|
|
|
|
Backend |
|
|
|
|
|
}) |
|
|
|
|
|
}. |
|
|
|
|
|
|
|
|
|
|
|
%% @doc Set the loglevel for a particular backend. |
|
|
%% @doc Set the loglevel for a particular backend. |
|
|
setLogLevel(Handler, Level) when is_atom(Level) -> |
|
|
setLogLevel(Handler, Level) when is_atom(Level) -> |
|
|
setLogLevel(?RumDefSink, Handler, undefined, Level). |
|
|
setLogLevel(?RumDefSink, Handler, undefined, Level). |
|
@ -207,66 +186,91 @@ setLogHwm(Sink, Handler, Hwm) when is_integer(Hwm) -> |
|
|
setLogHwm(Sink, Handler, Ident, Hwm) when is_integer(Hwm) -> |
|
|
setLogHwm(Sink, Handler, Ident, Hwm) when is_integer(Hwm) -> |
|
|
gen_emm:call(Sink, {Handler, Ident}, {mSetLogHwm, Hwm}, infinity). |
|
|
gen_emm:call(Sink, {Handler, Ident}, {mSetLogHwm, Hwm}, infinity). |
|
|
|
|
|
|
|
|
%% @doc Print stacktrace in human readable form |
|
|
|
|
|
pr_stacktrace(Stacktrace) -> |
|
|
|
|
|
Stacktrace1 = |
|
|
|
|
|
case rumUtil:get_env(rPrettyStrace, true) of |
|
|
|
|
|
true -> |
|
|
|
|
|
lists:reverse(Stacktrace); |
|
|
|
|
|
_ -> |
|
|
|
|
|
Stacktrace |
|
|
|
|
|
end, |
|
|
|
|
|
pr_stacktrace_(Stacktrace1). |
|
|
|
|
|
|
|
|
|
|
|
pr_stacktrace_(Stacktrace) -> |
|
|
|
|
|
Indent = "\n ", |
|
|
|
|
|
lists:foldl( |
|
|
|
|
|
fun(Entry, Acc) -> |
|
|
|
|
|
Acc ++ Indent ++ binary_to_list(rumErrLoggerH:formatMfa(Entry)) |
|
|
|
|
|
end, |
|
|
|
|
|
[], |
|
|
|
|
|
Stacktrace). |
|
|
|
|
|
|
|
|
|
|
|
pr_stacktrace(Stacktrace, {Class, Reason}) -> |
|
|
|
|
|
case rumUtil:get_env(rPrettyStrace, true) of |
|
|
|
|
|
|
|
|
%% @doc recalculate min log level |
|
|
|
|
|
upLogLevelCfg(error_logger) -> |
|
|
|
|
|
%% Not a sink under our control, part of the Erlang logging |
|
|
|
|
|
%% utility that error_logger_lager_h attaches to |
|
|
|
|
|
true; |
|
|
|
|
|
upLogLevelCfg(Sink) -> |
|
|
|
|
|
Traces = rumConfig:ptGet({Sink, trace}, []), |
|
|
|
|
|
AllLogLevel = allLogLevel(getLogLevels(Sink), 0), |
|
|
|
|
|
case Traces /= [] of |
|
|
true -> |
|
|
true -> |
|
|
lists:flatten( |
|
|
|
|
|
pr_stacktrace_(lists:reverse(Stacktrace)) ++ "\n" ++ io_lib:format("~s:~p", [Class, Reason])); |
|
|
|
|
|
|
|
|
ets:insert(?eRumEts, {Sink, 16#ff}), |
|
|
|
|
|
AllSinks = ets:tab2list(?eRumEts), |
|
|
|
|
|
rumKvsToBeam:load(?eRumCfg, AllSinks); |
|
|
_ -> |
|
|
_ -> |
|
|
lists:flatten( |
|
|
|
|
|
io_lib:format("~s:~p", [Class, Reason]) ++ pr_stacktrace_(Stacktrace)) |
|
|
|
|
|
|
|
|
ets:insert(?eRumEts, {Sink, AllLogLevel}), |
|
|
|
|
|
AllSinks = ets:tab2list(?eRumEts), |
|
|
|
|
|
rumKvsToBeam:load(?eRumCfg, AllSinks) |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
rotate_sink(Sink) -> |
|
|
|
|
|
|
|
|
allLogLevel([], Acc) -> |
|
|
|
|
|
Acc; |
|
|
|
|
|
allLogLevel([OneLv | Levels], Acc) -> |
|
|
|
|
|
allLogLevel(Levels, OneLv bor Acc). |
|
|
|
|
|
|
|
|
|
|
|
rotateSink(Sink) -> |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
RotateHandlers = lists:filtermap( |
|
|
RotateHandlers = lists:filtermap( |
|
|
fun({Handler, _, S}) when S == Sink -> {true, {Handler, Sink}}; |
|
|
fun({Handler, _, S}) when S == Sink -> {true, {Handler, Sink}}; |
|
|
(_) -> false |
|
|
(_) -> false |
|
|
end, |
|
|
end, |
|
|
Handlers), |
|
|
Handlers), |
|
|
rotate_handlers(RotateHandlers). |
|
|
|
|
|
|
|
|
rotateHandlers(RotateHandlers). |
|
|
|
|
|
|
|
|
rotate_all() -> |
|
|
|
|
|
rotate_handlers(lists:map(fun({H, _, S}) -> {H, S} end, |
|
|
|
|
|
|
|
|
rotateAll() -> |
|
|
|
|
|
rotateHandlers(lists:map(fun({H, _, S}) -> {H, S} end, |
|
|
rumConfig:ptGet(handlers, []))). |
|
|
rumConfig:ptGet(handlers, []))). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rotate_handlers(Handlers) -> |
|
|
|
|
|
[rotate_handler(Handler, Sink) || {Handler, Sink} <- Handlers]. |
|
|
|
|
|
|
|
|
rotateHandlers(Handlers) -> |
|
|
|
|
|
[rotateHandler(Handler, Sink) || {Handler, Sink} <- Handlers]. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rotate_handler(Handler) -> |
|
|
|
|
|
|
|
|
rotateHandler(Handler) -> |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
case lists:keyfind(Handler, 1, Handlers) of |
|
|
case lists:keyfind(Handler, 1, Handlers) of |
|
|
{Handler, _, Sink} -> rotate_handler(Handler, Sink); |
|
|
|
|
|
|
|
|
{Handler, _, Sink} -> rotateHandler(Handler, Sink); |
|
|
false -> ok |
|
|
false -> ok |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
rotate_handler(Handler, Sink) -> |
|
|
|
|
|
|
|
|
rotateHandler(Handler, Sink) -> |
|
|
gen_emm:call(Sink, Handler, mRotate, ?RumRotateTimeout). |
|
|
gen_emm:call(Sink, Handler, mRotate, ?RumRotateTimeout). |
|
|
|
|
|
|
|
|
|
|
|
%% @doc Print stacktrace in human readable form |
|
|
|
|
|
parseStack(Stacktrace) -> |
|
|
|
|
|
<< |
|
|
|
|
|
begin |
|
|
|
|
|
case Location of |
|
|
|
|
|
[] -> |
|
|
|
|
|
<<" ", (atom_to_binary(Mod, utf8))/binary, ":", (atom_to_binary(Func, utf8))/binary, "(", (eFmt:formatBin("~w", [Arity]))/binary, ")\n">>; |
|
|
|
|
|
[{file, File}, {line, Line}] -> |
|
|
|
|
|
<<" ", (atom_to_binary(Mod, utf8))/binary, ":", (atom_to_binary(Func, utf8))/binary, "/", (integer_to_binary(Arity))/binary, "(", (unicode:characters_to_binary(File))/binary, ":", (integer_to_binary(Line))/binary, ")\n">>; |
|
|
|
|
|
_ -> |
|
|
|
|
|
<<" ", (atom_to_binary(Mod, utf8))/binary, ":", (atom_to_binary(Func, utf8))/binary, "(", (eFmt:formatBin("~w", [Arity]))/binary, ")", (eFmt:formatBin("~w", [Location]))/binary, "\n">> |
|
|
|
|
|
end |
|
|
|
|
|
end || {Mod, Func, Arity, Location} <- Stacktrace |
|
|
|
|
|
>>. |
|
|
|
|
|
|
|
|
|
|
|
parseStack(Stacktrace, Class, Reason) -> |
|
|
|
|
|
eFmt:formatBin(<<"~n Class:~s~n Reason:~p~n Stacktrace:~s">>, [Class, Reason, parseStack(Stacktrace)]). |
|
|
|
|
|
|
|
|
trace_file(File, Filter) -> |
|
|
|
|
|
|
|
|
trace(BkdMod, Filter) -> |
|
|
|
|
|
trace(BkdMod, Filter, debug). |
|
|
|
|
|
|
|
|
|
|
|
trace({rumBkdFile, File}, Filter, Level) -> |
|
|
|
|
|
trace_file(File, Filter, Level); |
|
|
|
|
|
trace(Backend, Filter, Level) -> |
|
|
|
|
|
case validateTraceFilters(Filter, Level, Backend) of |
|
|
|
|
|
{Sink, {ok, Trace}} -> |
|
|
|
|
|
add_trace_to_loglevel_config(Trace, Sink), |
|
|
|
|
|
{ok, {Backend, Filter, Level}}; |
|
|
|
|
|
{_Sink, Error} -> |
|
|
|
|
|
Error |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
traceFile(File, Filter) -> |
|
|
trace_file(File, Filter, debug, []). |
|
|
trace_file(File, Filter, debug, []). |
|
|
|
|
|
|
|
|
trace_file(File, Filter, Level) when is_atom(Level) -> |
|
|
trace_file(File, Filter, Level) when is_atom(Level) -> |
|
@ -277,7 +281,7 @@ trace_file(File, Filter, Options) when is_list(Options) -> |
|
|
|
|
|
|
|
|
trace_file(File, Filter, Level, Options) -> |
|
|
trace_file(File, Filter, Level, Options) -> |
|
|
FileName = rumUtil:parsePath(File), |
|
|
FileName = rumUtil:parsePath(File), |
|
|
case validate_trace_filters(Filter, Level, {rumBkdFile, FileName}) of |
|
|
|
|
|
|
|
|
case validateTraceFilters(Filter, Level, {rumBkdFile, FileName}) of |
|
|
{Sink, {ok, Trace}} -> |
|
|
{Sink, {ok, Trace}} -> |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
Handlers = rumConfig:ptGet(handlers, []), |
|
|
%% check if this file backend is already installed |
|
|
%% check if this file backend is already installed |
|
@ -317,23 +321,8 @@ trace_console(Filter) -> |
|
|
trace_console(Filter, Level) -> |
|
|
trace_console(Filter, Level) -> |
|
|
trace(rumBkdConsole, Filter, Level). |
|
|
trace(rumBkdConsole, Filter, Level). |
|
|
|
|
|
|
|
|
trace(Backend, Filter) -> |
|
|
|
|
|
trace(Backend, Filter, debug). |
|
|
|
|
|
|
|
|
|
|
|
trace({rumBkdFile, File}, Filter, Level) -> |
|
|
|
|
|
trace_file(File, Filter, Level); |
|
|
|
|
|
|
|
|
|
|
|
trace(Backend, Filter, Level) -> |
|
|
|
|
|
case validate_trace_filters(Filter, Level, Backend) of |
|
|
|
|
|
{Sink, {ok, Trace}} -> |
|
|
|
|
|
add_trace_to_loglevel_config(Trace, Sink), |
|
|
|
|
|
{ok, {Backend, Filter, Level}}; |
|
|
|
|
|
{_Sink, Error} -> |
|
|
|
|
|
Error |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
stop_trace(Backend, Filter, Level) -> |
|
|
stop_trace(Backend, Filter, Level) -> |
|
|
case validate_trace_filters(Filter, Level, Backend) of |
|
|
|
|
|
|
|
|
case validateTraceFilters(Filter, Level, Backend) of |
|
|
{Sink, {ok, Trace}} -> |
|
|
{Sink, {ok, Trace}} -> |
|
|
stop_trace_int(Trace, Sink); |
|
|
stop_trace_int(Trace, Sink); |
|
|
{_Sink, Error} -> |
|
|
{_Sink, Error} -> |
|
@ -343,6 +332,17 @@ stop_trace(Backend, Filter, Level) -> |
|
|
stop_trace({Backend, Filter, Level}) -> |
|
|
stop_trace({Backend, Filter, Level}) -> |
|
|
stop_trace(Backend, Filter, Level). |
|
|
stop_trace(Backend, Filter, Level). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
validateTraceFilters(Filters, Level, Backend) -> |
|
|
|
|
|
Sink = proplists:get_value(sink, Filters, ?RumDefSink), |
|
|
|
|
|
{Sink, |
|
|
|
|
|
rumUtil:validate_trace({ |
|
|
|
|
|
proplists:delete(sink, Filters), |
|
|
|
|
|
Level, |
|
|
|
|
|
Backend |
|
|
|
|
|
}) |
|
|
|
|
|
}. |
|
|
|
|
|
|
|
|
%% Important: validate_trace_filters orders the arguments of |
|
|
%% Important: validate_trace_filters orders the arguments of |
|
|
%% trace tuples differently than the way outside callers have |
|
|
%% trace tuples differently than the way outside callers have |
|
|
%% the trace tuple. |
|
|
%% the trace tuple. |
|
@ -491,16 +491,6 @@ get_sink_handler_status(Sink, Handler, Level) -> |
|
|
[] |
|
|
[] |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
%% @doc Try to convert an atom to a posix error, but fall back on printing the |
|
|
|
|
|
%% term if its not a valid posix error code. |
|
|
|
|
|
posix_error(Error) when is_atom(Error) -> |
|
|
|
|
|
case erl_posix_msg:message(Error) of |
|
|
|
|
|
"unknown POSIX error" -> atom_to_list(Error); |
|
|
|
|
|
Message -> Message |
|
|
|
|
|
end; |
|
|
|
|
|
posix_error(Error) -> |
|
|
|
|
|
safe_format_chop("~p", [Error], ?RumDefTruncation). |
|
|
|
|
|
|
|
|
|
|
|
%% @private |
|
|
%% @private |
|
|
add_trace_to_loglevel_config(Trace, Sink) -> |
|
|
add_trace_to_loglevel_config(Trace, Sink) -> |
|
|
Traces = rumConfig:ptGet({Sink, trace}, []), |
|
|
Traces = rumConfig:ptGet({Sink, trace}, []), |
|
@ -514,49 +504,23 @@ add_trace_to_loglevel_config(Trace, Sink) -> |
|
|
ok |
|
|
ok |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
%% @doc recalculate min log level |
|
|
|
|
|
upLogLevelCfg(error_logger) -> |
|
|
|
|
|
%% Not a sink under our control, part of the Erlang logging |
|
|
|
|
|
%% utility that error_logger_lager_h attaches to |
|
|
|
|
|
true; |
|
|
|
|
|
upLogLevelCfg(Sink) -> |
|
|
|
|
|
Traces = rumConfig:ptGet({Sink, trace}, []), |
|
|
|
|
|
AllLogLevel = allLogLevel(getLogLevels(Sink), 0), |
|
|
|
|
|
case Traces /= [] of |
|
|
|
|
|
true -> |
|
|
|
|
|
ets:insert(?eRumEts, {Sink, 16#ff}), |
|
|
|
|
|
AllSinks = ets:tab2list(?eRumEts), |
|
|
|
|
|
rumKvsToBeam:load(?eRumCfg, AllSinks); |
|
|
|
|
|
_ -> |
|
|
|
|
|
ets:insert(?eRumEts, {Sink, AllLogLevel}), |
|
|
|
|
|
AllSinks = ets:tab2list(?eRumEts), |
|
|
|
|
|
rumKvsToBeam:load(?eRumCfg, AllSinks) |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
allLogLevel([], Acc) -> |
|
|
|
|
|
Acc; |
|
|
|
|
|
allLogLevel([OneLv | Levels], Acc) -> |
|
|
|
|
|
allLogLevel(Levels, OneLv bor Acc). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%% @doc Print the format string `Fmt' with `Args' safely with a size |
|
|
%% @doc Print the format string `Fmt' with `Args' safely with a size |
|
|
%% limit of `Limit'. If the format string is invalid, or not enough |
|
|
%% limit of `Limit'. If the format string is invalid, or not enough |
|
|
%% arguments are supplied 'FORMAT ERROR' is printed with the offending |
|
|
%% arguments are supplied 'FORMAT ERROR' is printed with the offending |
|
|
%% arguments. The caller is NOT crashed. |
|
|
%% arguments. The caller is NOT crashed. |
|
|
|
|
|
|
|
|
safe_format(Fmt, Args, Limit) -> |
|
|
|
|
|
safe_format_2(Fmt, Args, Limit). |
|
|
|
|
|
|
|
|
unsafeFormat(Fmt, Args) -> |
|
|
|
|
|
try io_lib:format(Fmt, Args) |
|
|
|
|
|
catch |
|
|
|
|
|
_:_ -> io_lib:format("FORMAT ERROR: ~p ~p", [Fmt, Args]) |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
safe_format_2(Fmt, Args, Limit) -> |
|
|
|
|
|
|
|
|
safeFormat(Fmt, Args, Limit) -> |
|
|
try eFmt:formatBin(Fmt, Args, [{charsLimit, Limit}]) |
|
|
try eFmt:formatBin(Fmt, Args, [{charsLimit, Limit}]) |
|
|
catch |
|
|
catch |
|
|
_:_ -> eFmt:formatBin(<<"FORMAT ERROR: ~p ~p">>, [Fmt, Args], [{charsLimit, Limit}]) |
|
|
_:_ -> eFmt:formatBin(<<"FORMAT ERROR: ~p ~p">>, [Fmt, Args], [{charsLimit, Limit}]) |
|
|
end. |
|
|
end. |
|
|
|
|
|
|
|
|
%% @private |
|
|
|
|
|
safe_format_chop(Fmt, Args, Limit) -> |
|
|
|
|
|
safe_format_2(Fmt, Args, Limit). |
|
|
|
|
|
|
|
|
|
|
|
%% @private Print the format string `Fmt' with `Args' without a size limit. |
|
|
%% @private Print the format string `Fmt' with `Args' without a size limit. |
|
|
%% This is unsafe because the output of this function is unbounded. |
|
|
%% This is unsafe because the output of this function is unbounded. |
|
|
%% |
|
|
%% |
|
@ -568,75 +532,6 @@ safe_format_chop(Fmt, Args, Limit) -> |
|
|
%% If the format string is invalid or not enough arguments are |
|
|
%% If the format string is invalid or not enough arguments are |
|
|
%% supplied a 'FORMAT ERROR' message is printed instead with the |
|
|
%% supplied a 'FORMAT ERROR' message is printed instead with the |
|
|
%% offending arguments. The caller is NOT crashed. |
|
|
%% offending arguments. The caller is NOT crashed. |
|
|
unsafe_format(Fmt, Args) -> |
|
|
|
|
|
try io_lib:format(Fmt, Args) |
|
|
|
|
|
catch |
|
|
|
|
|
_:_ -> io_lib:format("FORMAT ERROR: ~p ~p", [Fmt, Args]) |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
%% @doc Print a record or a list of records lager found during parse transform |
|
|
|
|
|
pr(Record, Module) when is_tuple(Record), is_atom(element(1, Record)) -> |
|
|
|
|
|
pr(Record, Module, []); |
|
|
|
|
|
pr(List, Module) when is_list(List) -> |
|
|
|
|
|
pr(List, Module, []); |
|
|
|
|
|
pr(Record, _) -> |
|
|
|
|
|
Record. |
|
|
|
|
|
|
|
|
|
|
|
%% @doc Print a record or a list of records lager found during parse transform |
|
|
|
|
|
pr(Record, Module, Options) when is_tuple(Record), is_atom(element(1, Record)), is_list(Options) -> |
|
|
|
|
|
try |
|
|
|
|
|
case is_record_known(Record, Module) of |
|
|
|
|
|
false -> |
|
|
|
|
|
Record; |
|
|
|
|
|
{RecordName, RecordFields} -> |
|
|
|
|
|
{'$lager_record', RecordName, |
|
|
|
|
|
zip(RecordFields, tl(tuple_to_list(Record)), Module, Options, [])} |
|
|
|
|
|
end |
|
|
|
|
|
catch |
|
|
|
|
|
error:undef -> |
|
|
|
|
|
Record |
|
|
|
|
|
end; |
|
|
|
|
|
pr([Head | Tail], Module, Options) when is_list(Options) -> |
|
|
|
|
|
[pr(Head, Module, Options) | pr(Tail, Module, Options)]; |
|
|
|
|
|
pr(Record, _, _) -> |
|
|
|
|
|
Record. |
|
|
|
|
|
|
|
|
|
|
|
zip([FieldName | RecordFields], [FieldValue | Record], Module, Options, ToReturn) when is_list(FieldValue) -> |
|
|
|
|
|
zip(RecordFields, Record, Module, Options, |
|
|
|
|
|
[{FieldName, pr(FieldValue, Module, Options)} | ToReturn]); |
|
|
|
|
|
zip([FieldName | RecordFields], [FieldValue | Record], Module, Options, ToReturn) -> |
|
|
|
|
|
Compress = lists:member(compress, Options), |
|
|
|
|
|
case is_tuple(FieldValue) andalso |
|
|
|
|
|
tuple_size(FieldValue) > 0 andalso |
|
|
|
|
|
is_atom(element(1, FieldValue)) andalso |
|
|
|
|
|
is_record_known(FieldValue, Module) of |
|
|
|
|
|
false when Compress andalso FieldValue =:= undefined -> |
|
|
|
|
|
zip(RecordFields, Record, Module, Options, ToReturn); |
|
|
|
|
|
false -> |
|
|
|
|
|
zip(RecordFields, Record, Module, Options, [{FieldName, FieldValue} | ToReturn]); |
|
|
|
|
|
_Else -> |
|
|
|
|
|
F = {FieldName, pr(FieldValue, Module, Options)}, |
|
|
|
|
|
zip(RecordFields, Record, Module, Options, [F | ToReturn]) |
|
|
|
|
|
end; |
|
|
|
|
|
zip([], [], _Module, _Compress, ToReturn) -> |
|
|
|
|
|
lists:reverse(ToReturn). |
|
|
|
|
|
|
|
|
|
|
|
is_record_known(Record, Module) -> |
|
|
|
|
|
Name = element(1, Record), |
|
|
|
|
|
Attrs = Module:module_info(attributes), |
|
|
|
|
|
case lists:keyfind(lager_records, 1, Attrs) of |
|
|
|
|
|
false -> false; |
|
|
|
|
|
{lager_records, Records} -> |
|
|
|
|
|
case lists:keyfind(Name, 1, Records) of |
|
|
|
|
|
false -> false; |
|
|
|
|
|
{Name, RecordFields} -> |
|
|
|
|
|
case (tuple_size(Record) - 1) =:= length(RecordFields) of |
|
|
|
|
|
false -> false; |
|
|
|
|
|
true -> {Name, RecordFields} |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%% @private |
|
|
%% @private |
|
|
trace_func(#trace_func_state_v1{pid = Pid, level = Level, format_string = Fmt} = FuncState, Event, ProcState) -> |
|
|
trace_func(#trace_func_state_v1{pid = Pid, level = Level, format_string = Fmt} = FuncState, Event, ProcState) -> |
|
|