Merge pull request #196 from basho/adt-less-proplists

Don't use the proplists module when decoding error_logger messages
diff --git a/src/lager.erl b/src/lager.erl
index 1931d69..c075544 100644
--- a/src/lager.erl
+++ b/src/lager.erl
@@ -362,30 +362,45 @@
 
 %% @doc Print a record lager found during parse transform
 pr(Record, Module) when is_tuple(Record), is_atom(element(1, Record)) ->
-    try Module:module_info(attributes) of
-        Attrs ->
-            case lists:keyfind(lager_records, 1, Attrs) of
-                false ->
-                    Record;
-                {lager_records, Records} ->
-                    RecordName = element(1, Record),
-                    RecordSize = tuple_size(Record) - 1,
-                    case lists:filter(fun({Name, Fields}) when Name == RecordName,
-                                length(Fields) == RecordSize ->
-                                    true;
-                                (_) ->
-                                    false
-                            end, Records) of
-                        [] ->
-                            Record;
-                        [{RecordName, RecordFields}|_] ->
-                            {'$lager_record', RecordName,
-                                lists:zip(RecordFields, tl(tuple_to_list(Record)))}
-                    end
-            end
+    try 
+        case is_record_known(Record, Module) of
+            false ->
+                Record;
+            {RecordName, RecordFields} ->
+                {'$lager_record', RecordName, 
+                    zip(RecordFields, tl(tuple_to_list(Record)), Module, [])}
+        end
     catch
         error:undef ->
             Record
     end;
 pr(Record, _) ->
     Record.
+
+zip([FieldName|RecordFields], [FieldValue|Record], Module, ToReturn) ->
+    case  is_tuple(FieldValue) andalso is_atom(element(1, FieldValue))
+           andalso is_record_known(FieldValue, Module) of
+        false ->
+            zip(RecordFields, Record, Module, [{FieldName, FieldValue}|ToReturn]);
+        _Else ->
+            F = {FieldName, pr(FieldValue, Module)},
+            zip(RecordFields, Record, Module, [F|ToReturn])
+    end;
+zip([], [], _Module, 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.
diff --git a/src/lager_console_backend.erl b/src/lager_console_backend.erl
index ca203ad..4d9c4e3 100644
--- a/src/lager_console_backend.erl
+++ b/src/lager_console_backend.erl
@@ -1,4 +1,4 @@
-%% Copyright (c) 2011-2012 Basho Technologies, Inc.  All Rights Reserved.
+%% Copyright (c) 2011-2012, 2014 Basho Technologies, Inc.  All Rights Reserved.
 %%
 %% This file is provided to you under the Apache License,
 %% Version 2.0 (the "License"); you may not use this file
@@ -44,7 +44,7 @@
     init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]);
 init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
     Colors = case application:get_env(lager, colored) of
-        {ok, true} -> 
+        {ok, true} ->
             {ok, LagerColors} = application:get_env(lager, colors),
             LagerColors;
         _ -> []
@@ -65,7 +65,7 @@
             {error, {fatal, old_shell}};
         {true, Levels} ->
             {ok, #state{level=Levels,
-                    formatter=Formatter, 
+                    formatter=Formatter,
                     format_config=FormatterConfig,
                     colors=Colors}}
     catch
@@ -119,7 +119,7 @@
     case application:get_env(lager, colored) of
         {ok, true}  ->
             "\e[0m\r\n";
-        _ -> 
+        _ ->
             "\r\n"
     end.
 
@@ -139,7 +139,7 @@
     %%    'user_drv' is a registered proc name used by the "new"
     %%    console driver.
     init:get_argument(noshell) /= error orelse
-        element(1, os:type()) == win32 orelse
+        element(1, os:type()) /= win32 orelse
         is_pid(whereis(user_drv)).
 -endif.
 
@@ -224,7 +224,7 @@
                         unregister(user),
                         register(user, Pid),
                         erlang:group_leader(Pid, whereis(lager_event)),
-                        gen_event:add_handler(lager_event, lager_console_backend, 
+                        gen_event:add_handler(lager_event, lager_console_backend,
                           [info, {lager_default_formatter, [date,"#",time,"#",severity,"#",node,"#",pid,"#",
                                                             module,"#",function,"#",file,"#",line,"#",message,"\r\n"]}]),
                         lager_config:set(loglevel, {?INFO, []}),
@@ -235,7 +235,7 @@
                         receive
                             {io_request, _, _, {put_chars, unicode, Msg}} ->
                                 TestMsg = "Test message" ++ eol(),
-                                ?assertMatch([_, _, "info", NodeStr, PidStr, ModuleStr, _, _, _, TestMsg], 
+                                ?assertMatch([_, _, "info", NodeStr, PidStr, ModuleStr, _, _, _, TestMsg],
                                              re:split(Msg, "#", [{return, list}, {parts, 10}]))
                         after
                             500 ->
diff --git a/src/lager_crash_log.erl b/src/lager_crash_log.erl
index 089e32a..32e3728 100644
--- a/src/lager_crash_log.erl
+++ b/src/lager_crash_log.erl
@@ -188,7 +188,7 @@
         {error, _GL, {Pid1, Fmt, Args}} ->
             {"ERROR REPORT", Pid1, limited_fmt(Fmt, Args, FmtMaxBytes), true};
         {error_report, _GL, {Pid1, std_error, Rep}} ->
-            {"ERROR REPORT", Pid1, limited_str(Rep, FmtMaxBytes), true};
+            {"ERROR REPORT", Pid1, limited_str(Rep, FmtMaxBytes) ++ "\n", true};
         {error_report, _GL, Other} ->
             perhaps_a_sasl_report(error_report, Other, FmtMaxBytes);
         _ ->
diff --git a/test/pr_nested_record_test.erl b/test/pr_nested_record_test.erl
new file mode 100644
index 0000000..ee19ef7
--- /dev/null
+++ b/test/pr_nested_record_test.erl
@@ -0,0 +1,21 @@
+-module(pr_nested_record_test).
+
+-compile([{parse_transform, lager_transform}]).
+
+-record(a, {field1, field2}).
+-record(b, {field1, field2}).
+
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+-endif.
+
+nested_record_test() ->
+    A = #a{field1 = x, field2 = y}, 
+    B = #b{field1 = A, field2 = z},
+    Pr_B = lager:pr(B, ?MODULE),
+    ?assertEqual({'$lager_record', b,
+                    [{field1, {'$lager_record', a,
+                                    [{field1, x},{field2, y}]}},
+                     {field2, z}]}, 
+                   Pr_B).