瀏覽代碼

ft: 代码格式化

master
SisMaker 4 年之前
父節點
當前提交
60d551ee52
共有 11 個文件被更改,包括 86 次插入554 次删除
  1. +0
    -37
      README.md
  2. +1
    -0
      include/rumCom.hrl
  3. +3
    -3
      src/backend/rumBkdThrottle.erl
  4. +6
    -6
      src/crashLog/rumCrashLog.erl
  5. +47
    -35
      src/eRum.erl
  6. +4
    -5
      src/eRum_app.erl
  7. +0
    -2
      src/eRum_sup.erl
  8. +6
    -70
      src/utils/rumConfig.erl
  9. +0
    -393
      src/utils/rumStdlib.erl
  10. +19
    -1
      src/utils/rumUtil.erl
  11. +0
    -2
      进度.md

+ 0
- 37
README.md 查看文件

@ -24,15 +24,6 @@ eRum is a Erlang logger. 基于lager3.9.0 rewrite
-----
在应用程序中使用eRum,需要将其定义为rebar dep,或者使用其他方法将其包含在Erlang的dep路径中。然后添加下面的编译选项:
```erlang
{parse_transform, rumTransform}
```
或者,你可以将它添加到你希望编译的模块中,并启用日志记录:
```erlang
-compile([{parse_transform, rumTransform}]).
```
在记录任何消息之前,您需要启动eRum应用程序。eRum模块的start函数负责启动 加载并启动eRum需要的任何依赖项
@ -40,38 +31,10 @@ eRum is a Erlang logger. 基于lager3.9.0 rewrite
eRum:start().
```
You can also start eRum on startup with a switch to `erl`:
```erlang
erl -pa path/to/eRum/ebin -s eRum
```
一旦您用eRum构建了代码并启动了eRum应用程序,您就可以通过执行以下操作来生成日志消息:
```erlang
eRum:error("Some message")
eRum:warning("Some message with a term: ~p", [Term])
```
一般形式是`eRum:Severity()`,其中`Severity`是上面提到的日志级别之一。
配置选项
-------------
要配置eRum的后端,你需要使用一个应用程序变量(可能在app.config中):
```erlang
{eRum, [
%% log_root是可选的,默认情况下文件路径是相对于CWD的
{logRoot, "/var/log/hello"},
{handlers, [
{lager_console_backend, [{level, info}]},
{lager_file_backend, [{file, "error.log"}, {level, error}]},
{lager_file_backend, [{file, "console.log"}, {level, info}]}
]
}
]}.
```
每个后端可用的配置选项都列在它们的模块文档中。
接受器(Sinks)

+ 1
- 0
include/rumCom.hrl 查看文件

@ -4,6 +4,7 @@
%%
-define(eRumCfg, eRumCfg).
-define(eRumEts, eRumEts).
-define(eRumPtTl, eRumPtTl).
-define(RumDefSink, rumEvent).
-define(RumDefTruncation, 4096).

+ 3
- 3
src/backend/rumBkdThrottle.erl 查看文件

@ -28,7 +28,7 @@
}).
init([{sink, Sink}, Hwm, Window]) ->
rumConfig:set({Sink, async}, true),
rumConfig:ptSet({Sink, async}, true),
{ok, #state{sink = Sink, hwm = Hwm, window = Hwm - Window}}.
handleCall(mGetLogLevel, State) ->
@ -44,11 +44,11 @@ handleEvent({mWriteLog, _Message}, #state{hwm = Hwm, window = Window, async = As
if
MsgLen > Hwm andalso Async ->
%% need to flip to sync mode
rumConfig:set({State#state.sink, async}, false),
rumConfig:ptSet({State#state.sink, async}, false),
{ok, State#state{async = false}};
MsgLen < Window andalso not Async ->
%% need to flip to async mode
rumConfig:set({State#state.sink, async}, true),
rumConfig:ptSet({State#state.sink, async}, true),
{ok, State#state{async = true}};
true ->
%% nothing needs to change

+ 6
- 6
src/crashLog/rumCrashLog.erl 查看文件

@ -104,7 +104,7 @@ otherNodeSuffix(Pid) when node(Pid) =/= node() ->
end.
perhapsSaslReport(error_report, {Pid, Type, Report}, FmtMaxBytes) ->
case rumStdlib:isErrorReport(Type) of
case rumUtil:isErrorReport(Type) of
true ->
{saslTypeToReportHead(Type), Pid, saslLimitedStr(Type, Report, FmtMaxBytes), true};
false ->
@ -129,10 +129,10 @@ saslTypeToReportHead(progress) ->
<<"PROGRESS REPORT">>.
saslLimitedStr(supervisor_report, Report, FmtMaxBytes) ->
Name = rumStdlib:sup_get(supervisor, Report),
Context = rumStdlib:sup_get(errorContext, Report),
Reason = rumStdlib:sup_get(reason, Report),
Offender = rumStdlib:sup_get(offender, Report),
Name = rumUtil:sup_get(supervisor, Report),
Context = rumUtil:sup_get(errorContext, Report),
Reason = rumUtil:sup_get(reason, Report),
Offender = rumUtil:sup_get(offender, Report),
FmtString = <<" Supervisor: ~p~n Context: ~p~n Reason: "
"~s~n Offender: ~s~n~n">>,
ReasonStr = eFmt:formatBin(<<"~p">>, [Reason], [{charsLimit, FmtMaxBytes}]),
@ -144,7 +144,7 @@ saslLimitedStr(progress, Report, FmtMaxBytes) ->
eFmt:formatBin(" ~16w: ~s~n", [Tag, BinStr])
end || {Tag, Data} <- Report];
saslLimitedStr(crash_report, Report, FmtMaxBytes) ->
rumStdlib:proc_lib_format(Report, FmtMaxBytes).
eFmt:formatBin("~p~n", [Report], [{charsLimit, FmtMaxBytes}]).
writeLog(Event, #state{fileName = FileName, fd = FD, inode = Inode, cTime = CTime, flap = Flap, maxFmtSize = FmtMaxBytes, maxFileSize = RotSize, count = Count, rotator = Rotator} = State) ->
%% borrowed from riak_err

+ 47
- 35
src/eRum.erl 查看文件

@ -27,7 +27,7 @@
, setLogLevel/3
, setLogLevel/4
, getLogLevels/1
, updateLogevelCfg/1
, upLogLevelCfg/1
, setLogHwm/2
, setLogHwm/3
, setLogHwm/4
@ -105,7 +105,7 @@ do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args,
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},
case rumConfig:get({Sink, async}, false) of
case rumConfig:ptGet({Sink, async}, false) of
true ->
gen_emm:info_notify(Sink, {mWriteLog, RumMsg});
false ->
@ -173,7 +173,7 @@ setLogLevel(Sink, Handler, Ident, Level) when is_atom(Level) ->
_ -> {Handler, Ident}
end,
Reply = gen_emm:call(Sink, HandlerArg, {mSetLogLevel, Level}, infinity),
updateLogevelCfg(Sink),
upLogLevelCfg(Sink),
Reply.
@ -239,7 +239,7 @@ pr_stacktrace(Stacktrace, {Class, Reason}) ->
end.
rotate_sink(Sink) ->
Handlers = rumConfig:global_get(handlers),
Handlers = rumConfig:ptGet(handlers, []),
RotateHandlers = lists:filtermap(
fun({Handler, _, S}) when S == Sink -> {true, {Handler, Sink}};
(_) -> false
@ -249,7 +249,7 @@ rotate_sink(Sink) ->
rotate_all() ->
rotate_handlers(lists:map(fun({H, _, S}) -> {H, S} end,
rumConfig:global_get(handlers))).
rumConfig:ptGet(handlers, []))).
rotate_handlers(Handlers) ->
@ -257,7 +257,7 @@ rotate_handlers(Handlers) ->
rotate_handler(Handler) ->
Handlers = rumConfig:global_get(handlers),
Handlers = rumConfig:ptGet(handlers, []),
case lists:keyfind(Handler, 1, Handlers) of
{Handler, _, Sink} -> rotate_handler(Handler, Sink);
false -> ok
@ -280,7 +280,7 @@ trace_file(File, Filter, Level, Options) ->
FileName = rumUtil:parsePath(File),
case validate_trace_filters(Filter, Level, {rumBkdFile, FileName}) of
{Sink, {ok, Trace}} ->
Handlers = rumConfig:global_get(handlers, []),
Handlers = rumConfig:ptGet(handlers, []),
%% check if this file backend is already installed
Res =
case rumUtil:find_file(FileName, Handlers) of
@ -294,7 +294,7 @@ trace_file(File, Filter, Level, Options) ->
{level, none}),
HandlerInfo =
eRum_app:startHandler(Sink, {rumBkdFile, FileName}, LogFileConfig),
rumConfig:global_set(handlers, [HandlerInfo | Handlers]),
rumConfig:ptSet(handlers, [HandlerInfo | Handlers]),
{ok, installed};
{_Watcher, _Handler, Sink} ->
{ok, exists};
@ -354,20 +354,22 @@ stop_trace({Backend, Filter, Level}) ->
%% and when they come back from validation, they're
%% `{Filter, Level, Backend}'
stop_trace_int({_Filter, _Level, Backend} = Trace, Sink) ->
{Level, Traces} = rumConfig:get({Sink, loglevel}),
Traces = rumConfig:ptGet({Sink, trace}, []),
NewTraces = lists:delete(Trace, Traces),
_ = rumUtil:trace_filter([element(1, T) || T <- NewTraces]),
%MinLevel = minimum_loglevel(get_loglevels() ++ get_trace_levels(NewTraces)),
rumConfig:set({Sink, loglevel}, {Level, NewTraces}),
rumConfig:ptSet({Sink, trace}, NewTraces),
eRum:upLogLevelCfg(Sink),
case getLogLevel(Sink, Backend) of
none ->
%% check no other traces point here
case lists:keyfind(Backend, 3, NewTraces) of
false ->
gen_emm:delEpm(Sink, Backend, []),
rumConfig:global_set(handlers,
rumConfig:ptSet(handlers,
lists:keydelete(Backend, 1,
rumConfig:global_get(handlers)));
rumConfig:ptGet(handlers, [])));
_ ->
ok
end;
@ -396,17 +398,17 @@ list_all_sinks() ->
sets:add_element(Sink, Set)
end,
sets:new(),
rumConfig:global_get(handlers, []))).
rumConfig:ptGet(handlers, []))).
clear_traces_by_sink(Sinks) ->
lists:foreach(fun(S) ->
{Level, _Traces} =
rumConfig:get({S, loglevel}),
rumConfig:set({S, loglevel},
{Level, []})
end,
lists:foreach(
fun(S) ->
rumConfig:ptSet({S, trace}, []),
eRum:upLogLevelCfg(S)
end,
Sinks).
clear_trace_by_destination(ID) ->
Sinks = lists:sort(list_all_sinks()),
Traces = find_traces(Sinks),
@ -414,10 +416,10 @@ clear_trace_by_destination(ID) ->
clear_all_traces() ->
Handlers = rumConfig:global_get(handlers, []),
Handlers = rumConfig:ptGet(handlers, []),
clear_traces_by_sink(list_all_sinks()),
_ = rumUtil:trace_filter(none),
rumConfig:global_set(handlers,
rumConfig:ptSet(handlers,
lists:filter(
fun({Handler, _Watcher, Sink}) ->
case getLogLevel(Sink, Handler) of
@ -431,14 +433,14 @@ clear_all_traces() ->
find_traces(Sinks) ->
lists:foldl(fun(S, Acc) ->
{_Level, Traces} = rumConfig:get({S, loglevel}),
Traces = rumConfig:ptGet({S, trace}, []),
Acc ++ lists:map(fun(T) -> {S, T} end, Traces)
end,
[],
Sinks).
status() ->
Handlers = rumConfig:global_get(handlers, []),
Handlers = rumConfig:ptGet(handlers, []),
Sinks = lists:sort(list_all_sinks()),
Traces = find_traces(Sinks),
TraceCount = case length(Traces) of
@ -502,31 +504,41 @@ posix_error(Error) ->
%% @private
add_trace_to_loglevel_config(Trace, Sink) ->
{MinLevel, Traces} = rumConfig:get({Sink, loglevel}),
Traces = rumConfig:ptGet({Sink, trace}, []),
case lists:member(Trace, Traces) of
false ->
NewTraces = [Trace | Traces],
_ = rumUtil:trace_filter([element(1, T) || T <- NewTraces]),
rumConfig:set({Sink, loglevel}, {MinLevel, [Trace | Traces]});
rumConfig:ptSet({Sink, trace}, [Trace | Traces]),
eRum:upLogLevelCfg(Sink);
_ ->
ok
end.
%% @doc recalculate min log level
updateLogevelCfg(error_logger) ->
upLogLevelCfg(error_logger) ->
%% Not a sink under our control, part of the Erlang logging
%% utility that error_logger_lager_h attaches to
true;
updateLogevelCfg(Sink) ->
{_, Traces} = rumConfig:get({Sink, loglevel}, {ignore_me, []}),
MinLog = minLogLevel(getLogLevels(Sink)),
rumConfig:set({Sink, loglevel}, {MinLog, Traces}).
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).
minLogLevel(Levels) ->
lists:foldl(
fun(Mask, Acc) ->
Mask bor Acc
end, 0, Levels).
%% @doc Print the format string `Fmt' with `Args' safely with a size
%% limit of `Limit'. If the format string is invalid, or not enough

+ 4
- 5
src/eRum_app.erl 查看文件

@ -34,7 +34,7 @@ doStart() ->
%% error logger
SavedHandlers = tryStartErrLoggerHandler(rumUtil:get_env(errLoggerRedirect, true), rumUtil:get_env(errLoggerHwm, undefined), rumUtil:get_env(errLoggerWhitelist, [])),
eRum:updateLogevelCfg(?RumDefSink),
eRum:upLogLevelCfg(?RumDefSink),
SavedHandlers.
startSink(?RumDefSink) -> doStart();
@ -45,7 +45,6 @@ startSink(Sink) ->
startSink(Sink, SinkOpts).
startSink(Sink, Opts) ->
rumConfig:initSink(Sink),
ChildId = rumUtil:makeInnerSinkName(Sink),
SinkSpec = #{
id => ChildId,
@ -58,7 +57,7 @@ startSink(Sink, Opts) ->
tryStartAsyncMgr(proplists:get_value(asyncThreshold, Opts, undefined), proplists:get_value(asyncThrWindow, Opts, undefined), Sink),
tryInstallKiller(proplists:get_value(killerHwm, Opts, undefined), proplists:get_value(killerReTime, Opts, undefined), Sink),
tryStartHandlers(proplists:get_value(handlers, Opts, []), Sink),
eRum:updateLogevelCfg(Sink).
eRum:upLogLevelCfg(Sink).
doStartExtraSink() ->
doStartExtraSinks(rumUtil:get_env(extraSinks, [])).
@ -83,7 +82,7 @@ startTrace({Handler, Filter, Level}) when is_atom(Level) ->
stop(Handlers) ->
[error_logger:add_report_handler(Handler) || Handler <- Handlers],
rumConfig:cleanup().
ok.
tryStartAsyncMgr(undefined, _Window, _Sink) ->
ignore;
@ -110,7 +109,7 @@ tryStartHandlers(undefined, _Sink) -> ok;
tryStartHandlers(Handlers, Sink) ->
%% handler_watcher中处理
NewHandler = doStartHandlers(Handlers, Sink, [], []),
rumConfig:global_set(handlers, rumConfig:global_get(handlers, []) ++ NewHandler),
rumConfig:ptSet(handlers, rumConfig:ptGet(handlers, []) ++ NewHandler),
ok.
doStartHandlers([], _Sink, _NameAcc, HandlerAcc) ->

+ 0
- 2
src/eRum_sup.erl 查看文件

@ -35,8 +35,6 @@ start_link() ->
init(_Args) ->
%% set up the config, is safe even during relups
%% IMY-TODO
rumConfig:init(),
?eRumInit(),
%%runEvent作为默认值启动gen_event东西也许是一个用于处理接收器及其策略的新API
SupFlags =

+ 6
- 70
src/utils/rumConfig.erl 查看文件

@ -7,78 +7,14 @@
-compile({inline_size, 128}).
-export([
init/0
, initSink/1
, get/1
, get/2
, set/2
, global_get/1
, global_get/2
, global_set/2
, cleanup/0
ptGet/2
, ptSet/2
]).
-define(TBL, lager_config).
-define(GLOBAL, '_global').
ptGet(Key, Default) ->
persistent_term:get({?eRumPtTl, Key}, Default).
%% For multiple sinks, the key is now the registered event name and the old key as a tuple.
%% {{lager_event, loglevel}, Value} instead of {loglevel, Value}
ptSet(Key, Value) ->
persistent_term:put({?eRumPtTl, Key}, Value).
init() ->
initSink(?RumDefSink),
%% Need to be able to find the `lager_handler_watcher' for all handlers
insert_new({?GLOBAL, handlers}, []),
ok.
initSink(Sink) ->
%% use insert_new here so that if we're in an appup we don't mess anything up until lager is completely started, allow all messages to go through
insert_new({Sink, loglevel}, {rumUtil:configToMask(debug), []}).
global_get(Key) ->
global_get(Key, undefined).
global_get(Key, Default) ->
get({?GLOBAL, Key}, Default).
global_set(Key, Value) ->
set({?GLOBAL, Key}, Value).
get({_Sink, _Key} = FullKey) ->
get(FullKey, undefined);
get(Key) ->
get({?RumDefSink, Key}, undefined).
get({Sink, Key}, Default) ->
lookup({Sink, Key}, Default);
get(Key, Default) ->
get({?RumDefSink, Key}, Default).
set({Sink, Key}, Value) ->
insert({Sink, Key}, Value);
set(Key, Value) ->
set({?RumDefSink, Key}, Value).
insert(Key, Value) ->
persistent_term:put({?TBL, Key}, Value).
insert_new(Key, Value) ->
try persistent_term:get({?TBL, Key}) of
_Value ->
false
catch error:badarg ->
insert(Key, Value),
true
end.
lookup(Key, Default) ->
try persistent_term:get({?TBL, Key}) of
Value -> Value
catch
error:badarg ->
Default
end.
cleanup() ->
[persistent_term:erase(K) || {{?TBL, _} = K, _} <- persistent_term:get()].

+ 0
- 393
src/utils/rumStdlib.erl 查看文件

@ -1,393 +0,0 @@
-module(rumStdlib).
-compile(inline).
-compile({inline_size, 128}).
-export([
isErrorReport/1,
is_my_info_report/1
]).
-export([sup_get/2]).
-export([proc_lib_format/2]).
%% From OTP sasl's sasl_report.erl ... These functions aren't
%% exported.
-spec isErrorReport(atom()) -> boolean().
isErrorReport(supervisor_report) -> true;
isErrorReport(crash_report) -> true;
isErrorReport(_) -> false.
-spec is_my_info_report(atom()) -> boolean().
is_my_info_report(progress) -> true;
is_my_info_report(_) -> false.
-spec sup_get(term(), [proplists:property()]) -> term().
sup_get(Tag, Report) ->
case lists:keysearch(Tag, 1, Report) of
{value, {_, Value}} ->
Value;
_ ->
""
end.
%% From OTP stdlib's proc_lib.erl ... These functions aren't exported.
-spec proc_lib_format([term()], pos_integer()) -> string().
proc_lib_format([OwnReport, LinkReport], FmtMaxBytes) ->
OwnFormat = format_report(OwnReport, FmtMaxBytes),
LinkFormat = format_report(LinkReport, FmtMaxBytes),
%% io_lib:format here is OK because we're limiting max length elsewhere.
Str = io_lib:format(" crasher:~n~s neighbours:~n~s", [OwnFormat, LinkFormat]),
lists:flatten(Str).
format_report(Rep, FmtMaxBytes) when is_list(Rep) ->
format_rep(Rep, FmtMaxBytes);
format_report(Rep, FmtMaxBytes) ->
eFmt:formatBin(<<"~p~n">>, [Rep], [{charsLimit, FmtMaxBytes}]).
format_rep([{initial_call, InitialCall} | Rep], FmtMaxBytes) ->
[format_mfa(InitialCall, FmtMaxBytes) | format_rep(Rep, FmtMaxBytes)];
format_rep([{error_info, {Class, Reason, StackTrace}} | Rep], FmtMaxBytes) ->
[format_exception(Class, Reason, StackTrace, FmtMaxBytes) | format_rep(Rep, FmtMaxBytes)];
format_rep([{Tag, Data} | Rep], FmtMaxBytes) ->
[format_tag(Tag, Data, FmtMaxBytes) | format_rep(Rep, FmtMaxBytes)];
format_rep(_, _S) ->
[].
format_exception(Class, Reason, StackTrace, FmtMaxBytes) ->
PF = pp_fun(FmtMaxBytes),
StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end,
%% EI = " exception: ",
EI = " ",
[EI, lib_format_exception(1 + length(EI), Class, Reason,
StackTrace, StackFun, PF), "\n"].
format_mfa({M, F, Args} = StartF, FmtMaxBytes) ->
try
A = length(Args),
[" initial call: ", atom_to_list(M), $:, atom_to_list(F), $/,
integer_to_list(A), "\n"]
catch
error:_ ->
format_tag(initial_call, StartF, FmtMaxBytes)
end.
pp_fun(FmtMaxBytes) ->
fun(Term, _I) ->
eFmt:formatBin(<<"~p">>, [Term], [{charsLimit, FmtMaxBytes}])
end.
format_tag(Tag, Data, FmtMaxBytes) ->
eFmt:formatBin(<<"~p: ~p~n">>, [Tag, Data], [{charsLimit, FmtMaxBytes}]).
%% From OTP stdlib's lib.erl ... These functions aren't exported.
lib_format_exception(I, Class, Reason, StackTrace, StackFun, FormatFun)
when is_integer(I), I >= 1, is_function(StackFun, 3),
is_function(FormatFun, 2) ->
Str = n_spaces(I - 1),
{Term, Trace1, Trace} = analyze_exception(Class, Reason, StackTrace),
Expl0 = explain_reason(Term, Class, Trace1, FormatFun, Str),
Expl = io_lib:fwrite(<<"~s~s">>, [exited(Class), Expl0]),
case format_stacktrace1(Str, Trace, FormatFun, StackFun) of
[] -> Expl;
Stack -> [Expl, $\n, Stack]
end.
analyze_exception(error, Term, Stack) ->
case {is_stacktrace(Stack), Stack, Term} of
{true, [{_M, _F, As} = MFA | MFAs], function_clause} when is_list(As) ->
{Term, [MFA], MFAs};
{true, [{shell, F, A}], function_clause} when is_integer(A) ->
{Term, [{F, A}], []};
{true, [{_M, _F, _AorAs} = MFA | MFAs], undef} ->
{Term, [MFA], MFAs};
{true, _, _} ->
{Term, [], Stack};
{false, _, _} ->
{{Term, Stack}, [], []}
end;
analyze_exception(_Class, Term, Stack) ->
case is_stacktrace(Stack) of
true ->
{Term, [], Stack};
false ->
{{Term, Stack}, [], []}
end.
is_stacktrace([]) ->
true;
is_stacktrace([{M, F, A} | Fs]) when is_atom(M), is_atom(F), is_integer(A) ->
is_stacktrace(Fs);
is_stacktrace([{M, F, As} | Fs]) when is_atom(M), is_atom(F), length(As) >= 0 ->
is_stacktrace(Fs);
is_stacktrace(_) ->
false.
%% ERTS exit codes (some of them are also returned by erl_eval):
explain_reason(badarg, error, [], _PF, _Str) ->
<<"bad argument">>;
explain_reason({badarg, V}, error = Cl, [], PF, Str) -> % orelse, andalso
format_value(V, <<"bad argument: ">>, Cl, PF, Str);
explain_reason(badarith, error, [], _PF, _Str) ->
<<"bad argument in an arithmetic expression">>;
explain_reason({badarity, {Fun, As}}, error, [], _PF, _Str)
when is_function(Fun) ->
%% Only the arity is displayed, not the arguments As.
io_lib:fwrite(<<"~s called with ~s">>,
[format_fun(Fun), argss(length(As))]);
explain_reason({badfun, Term}, error = Cl, [], PF, Str) ->
format_value(Term, <<"bad function ">>, Cl, PF, Str);
explain_reason({badmatch, Term}, error = Cl, [], PF, Str) ->
format_value(Term, <<"no match of right hand side value ">>, Cl, PF, Str);
explain_reason({case_clause, V}, error = Cl, [], PF, Str) ->
%% "there is no case clause with a true guard sequence and a
%% pattern matching..."
format_value(V, <<"no case clause matching ">>, Cl, PF, Str);
explain_reason(function_clause, error, [{F, A}], _PF, _Str) ->
%% Shell commands
FAs = io_lib:fwrite(<<"~w/~w">>, [F, A]),
[<<"no function clause matching call to ">> | FAs];
explain_reason(function_clause, error = Cl, [{M, F, As}], PF, Str) ->
String = <<"no function clause matching ">>,
format_errstr_call(String, Cl, {M, F}, As, PF, Str);
explain_reason(if_clause, error, [], _PF, _Str) ->
<<"no true branch found when evaluating an if expression">>;
explain_reason(noproc, error, [], _PF, _Str) ->
<<"no such process or port">>;
explain_reason(notalive, error, [], _PF, _Str) ->
<<"the node cannot be part of a distributed system">>;
explain_reason(system_limit, error, [], _PF, _Str) ->
<<"a system limit has been reached">>;
explain_reason(timeout_value, error, [], _PF, _Str) ->
<<"bad receive timeout value">>;
explain_reason({try_clause, V}, error = Cl, [], PF, Str) ->
%% "there is no try clause with a true guard sequence and a
%% pattern matching..."
format_value(V, <<"no try clause matching ">>, Cl, PF, Str);
explain_reason(undef, error, [{M, F, A}], _PF, _Str) ->
%% Only the arity is displayed, not the arguments, if there are any.
io_lib:fwrite(<<"undefined function ~s">>,
[mfa_to_string(M, F, n_args(A))]);
explain_reason({shell_undef, F, A}, error, [], _PF, _Str) ->
%% Give nicer reports for undefined shell functions
%% (but not when the user actively calls shell_default:F(...)).
io_lib:fwrite(<<"undefined shell command ~s/~w">>, [F, n_args(A)]);
%% Exit codes returned by erl_eval only:
explain_reason({argument_limit, _Fun}, error, [], _PF, _Str) ->
io_lib:fwrite(<<"limit of number of arguments to interpreted function"
" exceeded">>, []);
explain_reason({bad_filter, V}, error = Cl, [], PF, Str) ->
format_value(V, <<"bad filter ">>, Cl, PF, Str);
explain_reason({bad_generator, V}, error = Cl, [], PF, Str) ->
format_value(V, <<"bad generator ">>, Cl, PF, Str);
explain_reason({unbound, V}, error, [], _PF, _Str) ->
io_lib:fwrite(<<"variable ~w is unbound">>, [V]);
%% Exit codes local to the shell module (restricted shell):
explain_reason({restricted_shell_bad_return, V}, exit = Cl, [], PF, Str) ->
String = <<"restricted shell module returned bad value ">>,
format_value(V, String, Cl, PF, Str);
explain_reason({restricted_shell_disallowed, {ForMF, As}},
exit = Cl, [], PF, Str) ->
%% ForMF can be a fun, but not a shell fun.
String = <<"restricted shell does not allow ">>,
format_errstr_call(String, Cl, ForMF, As, PF, Str);
explain_reason(restricted_shell_started, exit, [], _PF, _Str) ->
<<"restricted shell starts now">>;
explain_reason(restricted_shell_stopped, exit, [], _PF, _Str) ->
<<"restricted shell stopped">>;
%% Other exit code:
explain_reason(Reason, Class, [], PF, Str) ->
PF(Reason, (iolist_size(Str) + 1) + exited_size(Class)).
n_spaces(N) ->
lists:duplicate(N, $\s).
exited_size(Class) ->
iolist_size(exited(Class)).
exited(error) ->
<<"exception error: ">>;
exited(exit) ->
<<"exception exit: ">>;
exited(throw) ->
<<"exception throw: ">>.
format_stacktrace1(S0, Stack0, PF, SF) ->
Stack1 = lists:dropwhile(fun({M, F, A}) -> SF(M, F, A)
end, lists:reverse(Stack0)),
S = [" " | S0],
Stack = lists:reverse(Stack1),
format_stacktrace2(S, Stack, 1, PF).
format_stacktrace2(S, [{M, F, A} | Fs], N, PF) when is_integer(A) ->
[io_lib:fwrite(<<"~s~s ~s">>,
[sep(N, S), origin(N, M, F, A), mfa_to_string(M, F, A)])
| format_stacktrace2(S, Fs, N + 1, PF)];
format_stacktrace2(S, [{M, F, As} | Fs], N, PF) when is_list(As) ->
A = length(As),
CalledAs = [S, <<" called as ">>],
C = format_call("", CalledAs, {M, F}, As, PF),
[io_lib:fwrite(<<"~s~s ~s\n~s~s">>,
[sep(N, S), origin(N, M, F, A), mfa_to_string(M, F, A),
CalledAs, C])
| format_stacktrace2(S, Fs, N + 1, PF)];
format_stacktrace2(_S, [], _N, _PF) ->
"".
argss(0) ->
<<"no arguments">>;
argss(1) ->
<<"one argument">>;
argss(2) ->
<<"two arguments">>;
argss(I) ->
io_lib:fwrite(<<"~w arguments">>, [I]).
format_value(V, ErrStr, Class, PF, Str) ->
Pre1Sz = exited_size(Class),
Str1 = PF(V, Pre1Sz + iolist_size([Str, ErrStr]) + 1),
[ErrStr | case count_nl(Str1) of
N1 when N1 > 1 ->
Str2 = PF(V, iolist_size(Str) + 1 + Pre1Sz),
case count_nl(Str2) < N1 of
true ->
[$\n, Str, n_spaces(Pre1Sz) | Str2];
false ->
Str1
end;
_ ->
Str1
end].
format_fun(Fun) when is_function(Fun) ->
{module, M} = erlang:fun_info(Fun, module),
{name, F} = erlang:fun_info(Fun, name),
{arity, A} = erlang:fun_info(Fun, arity),
case erlang:fun_info(Fun, type) of
{type, local} when F =:= "" ->
io_lib:fwrite(<<"~w">>, [Fun]);
{type, local} when M =:= erl_eval ->
io_lib:fwrite(<<"interpreted function with arity ~w">>, [A]);
{type, local} ->
mfa_to_string(M, F, A);
{type, external} ->
mfa_to_string(M, F, A)
end.
format_errstr_call(ErrStr, Class, ForMForFun, As, PF, Pre0) ->
Pre1 = [Pre0 | n_spaces(exited_size(Class))],
format_call(ErrStr, Pre1, ForMForFun, As, PF).
format_call(ErrStr, Pre1, ForMForFun, As, PF) ->
Arity = length(As),
[ErrStr |
case is_op(ForMForFun, Arity) of
{yes, Op} ->
format_op(ErrStr, Pre1, Op, As, PF);
no ->
MFs = mf_to_string(ForMForFun, Arity),
I1 = iolist_size([Pre1, ErrStr | MFs]),
S1 = pp_arguments(PF, As, I1),
S2 = pp_arguments(PF, As, iolist_size([Pre1 | MFs])),
Long = count_nl(pp_arguments(PF, [a2345, b2345], I1)) > 0,
case Long or (count_nl(S2) < count_nl(S1)) of
true ->
[$\n, Pre1, MFs, S2];
false ->
[MFs, S1]
end
end].
mfa_to_string(M, F, A) ->
io_lib:fwrite(<<"~s/~w">>, [mf_to_string({M, F}, A), A]).
mf_to_string({M, F}, A) ->
case erl_internal:bif(M, F, A) of
true ->
io_lib:fwrite(<<"~w">>, [F]);
false ->
case is_op({M, F}, A) of
{yes, '/'} ->
io_lib:fwrite(<<"~w">>, [F]);
{yes, F} ->
atom_to_list(F);
no ->
io_lib:fwrite(<<"~w:~w">>, [M, F])
end
end;
mf_to_string(Fun, _A) when is_function(Fun) ->
format_fun(Fun);
mf_to_string(F, _A) ->
io_lib:fwrite(<<"~w">>, [F]).
n_args(A) when is_integer(A) ->
A;
n_args(As) when is_list(As) ->
length(As).
origin(1, M, F, A) ->
case is_op({M, F}, n_args(A)) of
{yes, F} -> <<"in operator ">>;
no -> <<"in function ">>
end;
origin(_N, _M, _F, _A) ->
<<"in call from">>.
sep(1, S) -> S;
sep(_, S) -> [$\n | S].
count_nl([E | Es]) ->
count_nl(E) + count_nl(Es);
count_nl($\n) ->
1;
count_nl(Bin) when is_binary(Bin) ->
count_nl(binary_to_list(Bin));
count_nl(_) ->
0.
is_op(ForMForFun, A) ->
try
{erlang, F} = ForMForFun,
_ = erl_internal:op_type(F, A),
{yes, F}
catch error:_ -> no
end.
format_op(ErrStr, Pre, Op, [A1, A2], PF) ->
I1 = iolist_size([ErrStr, Pre]),
S1 = PF(A1, I1 + 1),
S2 = PF(A2, I1 + 1),
OpS = atom_to_list(Op),
Pre1 = [$\n | n_spaces(I1)],
case count_nl(S1) > 0 of
true ->
[S1, Pre1, OpS, Pre1 | S2];
false ->
OpS2 = io_lib:fwrite(<<" ~s ">>, [Op]),
S2_2 = PF(A2, iolist_size([ErrStr, Pre, S1 | OpS2]) + 1),
case count_nl(S2) < count_nl(S2_2) of
true ->
[S1, Pre1, OpS, Pre1 | S2];
false ->
[S1, OpS2 | S2_2]
end
end.
pp_arguments(PF, As, I) ->
case {As, io_lib:printable_list(As)} of
{[Int | T], true} ->
L = integer_to_list(Int),
Ll = length(L),
A = list_to_atom(lists:duplicate(Ll, $a)),
S0 = binary_to_list(iolist_to_binary(PF([A | T], I + 1))),
brackets_to_parens([$[, L, string:sub_string(S0, 2 + Ll)]);
_ ->
brackets_to_parens(PF(As, I + 1))
end.
brackets_to_parens(S) ->
B = iolist_to_binary(S),
Sz = byte_size(B) - 2,
<<$[, R:Sz/binary, $]>> = B,
[$(, R, $)].

+ 19
- 1
src/utils/rumUtil.erl 查看文件

@ -34,8 +34,10 @@
, checkHwm/2
, makeInnerSinkName/1
, isFileChanged/3
, isErrorReport/1
, get_env/2
, get_opt/3
, sup_get/2
]).
levels() ->
@ -622,4 +624,20 @@ get_opt(Key, Opts, Def) ->
Def;
V ->
element(2, V)
end.
end.
-spec sup_get(term(), [proplists:property()]) -> term().
sup_get(Tag, Report) ->
case lists:keysearch(Tag, 1, Report) of
{value, {_, Value}} ->
Value;
_ ->
""
end.
%% From OTP sasl's sasl_report.erl ... These functions aren't
%% exported.
-spec isErrorReport(atom()) -> boolean().
isErrorReport(supervisor_report) -> true;
isErrorReport(crash_report) -> true;
isErrorReport(_) -> false.

+ 0
- 2
进度.md 查看文件

@ -22,9 +22,7 @@
# TODO
io_lib:format 替换为 eFmt:formatBin
reamde.me 整理
trace代码整理
eRumCfg相关代码添加

Loading…
取消
儲存