浏览代码

Function for printing stacktrace in human readable form

pull/298/head
Alexander Verbitsky 9 年前
父节点
当前提交
93f1c95894
共有 3 个文件被更改,包括 83 次插入1 次删除
  1. +13
    -0
      README.md
  2. +44
    -1
      src/lager.erl
  3. +26
    -0
      test/pr_stacktrace_test.erl

+ 13
- 0
README.md 查看文件

@ -392,6 +392,19 @@ Lager 2.0 changed the backend API, there are various 3rd party backends for
lager available, but they may not have been updated to the new API. As they lager available, but they may not have been updated to the new API. As they
are updated, links to them can be re-added here. are updated, links to them can be re-added here.
Exception Pretty Printing
----------------------
```erlang
try
foo()
catch
Class:Error ->
Stacktrace = lists:reverse(erlang:get_stacktrace()),
lager:error("~nStacktrace:~s~n~s:~p", [lager:pr_stacktrace(Stacktrace), Class, Error])
end.
```
Record Pretty Printing Record Pretty Printing
---------------------- ----------------------
Lager's parse transform will keep track of any record definitions it encounters Lager's parse transform will keep track of any record definitions it encounters

+ 44
- 1
src/lager.erl 查看文件

@ -33,7 +33,7 @@
get_loglevel/1, get_loglevel/2, set_loglevel/2, set_loglevel/3, set_loglevel/4, get_loglevels/1, get_loglevel/1, get_loglevel/2, set_loglevel/2, set_loglevel/3, set_loglevel/4, get_loglevels/1,
update_loglevel_config/1, posix_error/1, set_loghwm/2, set_loghwm/3, set_loghwm/4, update_loglevel_config/1, posix_error/1, set_loghwm/2, set_loghwm/3, set_loghwm/4,
safe_format/3, safe_format_chop/3, unsafe_format/2, dispatch_log/5, dispatch_log/7, dispatch_log/9, safe_format/3, safe_format_chop/3, unsafe_format/2, dispatch_log/5, dispatch_log/7, dispatch_log/9,
do_log/9, do_log/10, do_log_unsafe/10, pr/2, pr/3]).
do_log/9, do_log/10, do_log_unsafe/10, pr/2, pr/3, pr_stacktrace/1]).
-type log_level() :: debug | info | notice | warning | error | critical | alert | emergency. -type log_level() :: debug | info | notice | warning | error | critical | alert | emergency.
-type log_level_number() :: 0..7. -type log_level_number() :: 0..7.
@ -580,3 +580,46 @@ is_record_known(Record, Module) ->
end end
end. end.
%% @doc Print stacktrace in human readable form
pr_stacktrace([]) ->
<<"">>;
pr_stacktrace([Entry|Stacktrace]) ->
Indent = <<" ">>,
{Mod, Func, ArityOrArgs, Location} = Entry,
BinMod = atom_to_binary(Mod, utf8),
BinFunc = atom_to_binary(Func, utf8),
{Arity, Args} = case ArityOrArgs of
A when is_integer(A) -> {A, []};
_ ->
{length(ArityOrArgs), ArityOrArgs}
end,
BinArity = integer_to_binary(Arity),
FunSpec = <<"fun ", BinMod/binary, ":", BinFunc/binary, "/", BinArity/binary>>,
BinArgs = case Args of
[] -> <<"">>;
_ ->
BArgs = binary:replace(
list_to_binary(io_lib:format("~p", [Args])),
<<"\n">>, <<"">>, [global]),
<<"\n", Indent/binary, Indent/binary, "args ", BArgs/binary>>
end,
BinLocation = case Location of
[{file, File}, {line, Line}] ->
BLine = integer_to_binary(Line),
BFile = list_to_binary(File),
<<
"\n", Indent/binary, Indent/binary, "file \"", BFile/binary, "\"",
"\n", Indent/binary, Indent/binary, "line ", BLine/binary>>;
[] -> <<"">>
end,
Output = <<
"\n", Indent/binary, FunSpec/binary,
BinArgs/binary,
BinLocation/binary>>,
Rest = pr_stacktrace(Stacktrace),
<<Output/binary, Rest/binary>>.

+ 26
- 0
test/pr_stacktrace_test.erl 查看文件

@ -0,0 +1,26 @@
-module(pr_stacktrace_test).
-compile([{parse_transform, lager_transform}]).
-include_lib("eunit/include/eunit.hrl").
foo() ->
throw(test).
pr_stacktrace_test() ->
Result = try
foo()
catch
_Class:_Error ->
Stacktrace = lists:reverse(erlang:get_stacktrace()),
lager:pr_stacktrace(Stacktrace)
end,
ExpectedPart = <<"
fun pr_stacktrace_test:pr_stacktrace_test/0
file \"test/pr_stacktrace_test.erl\"
line 12
fun pr_stacktrace_test:foo/0
file \"test/pr_stacktrace_test.erl\"
line 8">>,
?assertNotEqual(nomatch, binary:match(Result, ExpectedPart, [])).

正在加载...
取消
保存