Browse Source

ft: 代码整理

master
SisMaker 4 years ago
parent
commit
6ed8c06675
6 changed files with 121 additions and 252 deletions
  1. +4
    -0
      README.md
  2. +0
    -2
      eRum.sample.config
  3. +3
    -3
      include/eRum.hrl
  4. +112
    -217
      src/eRum.erl
  5. +2
    -2
      src/utils/rumUtil.erl
  6. +0
    -28
      进度.md

+ 4
- 0
README.md View File

@ -2,6 +2,10 @@
--------
eRum is a Erlang logger. 基于lager3.9.0 rewrite
TODO
--------
trace相关代码整理
特点
--------

+ 0
- 2
eRum.sample.config View File

@ -55,8 +55,6 @@
%% ******************************************** format相关 ******************************************************
%% 元数据名单列表
{metadataWhitelist, []},
%% 是否美化堆栈
{rPrettyStrace, true},
%% ********************************************** 日志文件配置相关 ************************************************
%% 可选的日志路径, 默认情况下是当前路径

+ 3
- 3
include/eRum.hrl View File

@ -16,15 +16,15 @@
%% Level, Pid, Node, Module, Function, Line, Other
-define(rumLog(Severity, Format, Args, Safety),
?rumLog(?RumDefSink, Severity, self(), node(), ?MODULE, ?FUNCTION_NAME, ?LINE, eRum:md(), Format, Args, ?RumDefTruncation, Safety)).
?rumLog(?RumDefSink, Severity, self(), node(), ?MODULE, ?FUNCTION_NAME, ?LINE, eRum:getMd(), Format, Args, ?RumDefTruncation, Safety)).
-define(rumLog(Severity, Metadata, Format, Args, Safety),
?rumLog(?RumDefSink, Severity, self(), node(), ?MODULE, ?FUNCTION_NAME, ?LINE, Metadata ++ eRum:md(), Format, Args, ?RumDefTruncation, Safety)).
?rumLog(?RumDefSink, Severity, self(), node(), ?MODULE, ?FUNCTION_NAME, ?LINE, Metadata ++ eRum:getMd(), Format, Args, ?RumDefTruncation, Safety)).
-define(rumLog(Sink, Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Size, Safety),
case ?eRumCfg:get(Sink) band Severity /= 0 of
true ->
eRum:do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety);
eRum:doLogImpl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args, Severity, Size, Sink, Safety);
_ ->
ok
end).

+ 112
- 217
src/eRum.erl View File

@ -14,13 +14,12 @@
, stop/0
%% 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/2
, setLogLevel/2
@ -31,22 +30,19 @@
, setLogHwm/2
, setLogHwm/3
, 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/2
, trace/3
, trace_file/2
, traceFile/2
, trace_file/3
, trace_file/4
, trace_console/1
@ -79,27 +75,21 @@ start() ->
stop() ->
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)
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
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
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}, []),
{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(),
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},
@ -110,16 +100,16 @@ do_log_impl(Severity, Pid, Node, Module, Function, Line, Metadata, Format, Args,
false ->
gen_emm:call_notify(Sink, {mWriteLog, RumMsg})
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.
%% @doc Get lager metadata for current process
-spec md() -> [{atom(), any()}].
md() ->
-spec getMd() -> [{atom(), any()}].
getMd() ->
case erlang:get(?PdMdKey) of
undefined -> [];
MD -> MD
@ -127,8 +117,8 @@ md() ->
%% @doc Set lager metadata for current process.
%% 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
case lists:all(
fun({Key, _Value}) when is_atom(Key) -> true;
@ -137,23 +127,12 @@ md(NewMD) when is_list(NewMD) ->
true ->
erlang:put(?PdMdKey, NewMD),
ok;
false ->
_ ->
erlang:error(badarg)
end;
md(_) ->
setMd(_) ->
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.
setLogLevel(Handler, Level) when is_atom(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) ->
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 ->
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.
rotate_sink(Sink) ->
allLogLevel([], Acc) ->
Acc;
allLogLevel([OneLv | Levels], Acc) ->
allLogLevel(Levels, OneLv bor Acc).
rotateSink(Sink) ->
Handlers = rumConfig:ptGet(handlers, []),
RotateHandlers = lists:filtermap(
fun({Handler, _, S}) when S == Sink -> {true, {Handler, Sink}};
(_) -> false
end,
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, []))).
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, []),
case lists:keyfind(Handler, 1, Handlers) of
{Handler, _, Sink} -> rotate_handler(Handler, Sink);
{Handler, _, Sink} -> rotateHandler(Handler, Sink);
false -> ok
end.
rotate_handler(Handler, Sink) ->
rotateHandler(Handler, Sink) ->
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, Level) when is_atom(Level) ->
@ -277,7 +281,7 @@ trace_file(File, Filter, Options) when is_list(Options) ->
trace_file(File, Filter, Level, Options) ->
FileName = rumUtil:parsePath(File),
case validate_trace_filters(Filter, Level, {rumBkdFile, FileName}) of
case validateTraceFilters(Filter, Level, {rumBkdFile, FileName}) of
{Sink, {ok, Trace}} ->
Handlers = rumConfig:ptGet(handlers, []),
%% check if this file backend is already installed
@ -317,23 +321,8 @@ trace_console(Filter) ->
trace_console(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) ->
case validate_trace_filters(Filter, Level, Backend) of
case validateTraceFilters(Filter, Level, Backend) of
{Sink, {ok, Trace}} ->
stop_trace_int(Trace, Sink);
{_Sink, Error} ->
@ -343,6 +332,17 @@ 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
%% trace tuples differently than the way outside callers have
%% the trace tuple.
@ -491,16 +491,6 @@ get_sink_handler_status(Sink, Handler, Level) ->
[]
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
add_trace_to_loglevel_config(Trace, Sink) ->
Traces = rumConfig:ptGet({Sink, trace}, []),
@ -514,49 +504,23 @@ add_trace_to_loglevel_config(Trace, Sink) ->
ok
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
%% limit of `Limit'. If the format string is invalid, or not enough
%% arguments are supplied 'FORMAT ERROR' is printed with the offending
%% 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}])
catch
_:_ -> eFmt:formatBin(<<"FORMAT ERROR: ~p ~p">>, [Fmt, Args], [{charsLimit, Limit}])
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.
%% 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
%% supplied a 'FORMAT ERROR' message is printed instead with the
%% 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
trace_func(#trace_func_state_v1{pid = Pid, level = Level, format_string = Fmt} = FuncState, Event, ProcState) ->

+ 2
- 2
src/utils/rumUtil.erl View File

@ -504,9 +504,9 @@ parsePath(RelPath) ->
%% "logRoot"), but the file paths inside Handlers are not.
find_file(_File1, _Handlers = []) ->
false;
find_file(File1, [{{lager_file_backend, File2}, _Handler, _Sink} = HandlerInfo | Handlers]) ->
find_file(File1, [{{rumBkdFile, File2}, _Handler, _Sink} = HandlerInfo | Handlers]) ->
File1Abs = File1,
File2Abs = lager_util:expand_path(File2),
File2Abs = rumUtil:parsePath(File2),
case File1Abs =:= File2Abs of
true ->
% The file inside HandlerInfo is the same as the file we are looking

+ 0
- 28
进度.md View File

@ -1,28 +0,0 @@
# Done complete
eRum_sup
eRum.app.src
rumHWatcherSup
rumRotatorExm
# Done incomplete
app.config done
eRum_app
rumHWatcherSrv 部分还需要修改 删除测试代码
rumRotatorIns 旋转日志格式还需要修改
# Doing
# 优化改进之处:
日志旋转date格式转换函数修改(注释 对于某些月份 不存在29 30 或者 31天时 要避免M29 M30 M31的配法 代码并没有修复此种情况)
io_lib:format 修改为eFmt:format
# TODO
io_lib:format 替换为 eFmt:formatBin
trace代码整理

Loading…
Cancel
Save