Add colors to lager, not enabled by default
diff --git a/.gitignore b/.gitignore
index e04c657..ff8fc4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
 *.swp
 erl_crash.dump
 .project
+log
diff --git a/rebar.config b/rebar.config
index a9f18d7..97b3169 100644
--- a/rebar.config
+++ b/rebar.config
@@ -2,4 +2,4 @@
 {erl_first_files, ["src/lager_util.erl"]}.
 
 {cover_enabled, true}.
-{edoc_opts, [{stylesheet_file, "./priv/edoc.css"}]}.
\ No newline at end of file
+{edoc_opts, [{stylesheet_file, "./priv/edoc.css"}]}.
diff --git a/src/lager.app.src b/src/lager.app.src
index a9db914..e0d7ef0 100644
--- a/src/lager.app.src
+++ b/src/lager.app.src
@@ -20,6 +20,20 @@
                     {"log/console.log", info, 10485760, "$D0", 5}
                 ]}
             ]},
+            %% What colors to use with what log levels
+            {colored, false},
+            {colors, [
+              {debug,     "\e[0;38m" },
+              {info,      "\e[1;37m" },
+              {notice,    "\e[1;36m" },
+              {warning,   "\e[1;33m" },
+              {error,     "\e[1;31m" },
+              {critical,  "\e[1;35m" },
+              {alert,     "\e[1;44m" },
+              {emergency, "\e[1;41m" }
+
+            ]},
+
             %% Whether to write a crash log, and where. Undefined means no crash logger.
             {crash_log, "log/crash.log"},
             %% Maximum size in bytes of events in the crash log - defaults to 65536
diff --git a/src/lager_app.erl b/src/lager_app.erl
index b2a228b..352c4f3 100644
--- a/src/lager_app.erl
+++ b/src/lager_app.erl
@@ -78,11 +78,11 @@
             {ok, false} ->
                 [];
             _ ->
-                case application:get_env(lager, error_logger_whitelist) of
+                WhiteList = case application:get_env(lager, error_logger_whitelist) of
                     undefined ->
-                        WhiteList = [];
-                    {ok, WhiteList} ->
-                        WhiteList
+                        [];
+                    {ok, WhiteList0} ->
+                        WhiteList0
                 end,
 
                 case supervisor:start_child(lager_handler_watcher_sup, [error_logger, error_logger_lager_h, [HighWaterMark]]) of
diff --git a/src/lager_console_backend.erl b/src/lager_console_backend.erl
index 442204a..8f968e0 100644
--- a/src/lager_console_backend.erl
+++ b/src/lager_console_backend.erl
@@ -24,7 +24,7 @@
 -export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
         code_change/3]).
 
--record(state, {level, formatter,format_config}).
+-record(state, {level, formatter,format_config,colors=[]}).
 
 -ifdef(TEST).
 -include_lib("eunit/include/eunit.hrl").
@@ -32,26 +32,33 @@
 -endif.
 
 -include("lager.hrl").
-
--define(TERSE_FORMAT,[time, " [", severity,"] ", message, "\r\n"]).
+-define(TERSE_FORMAT,[time, " ", color, "[", severity,"] ", message]).
 
 %% @private
 init([Level, true]) -> % for backwards compatibility
-    init([Level,{lager_default_formatter,[{eol, "\r\n"}]}]);
+    init([Level,{lager_default_formatter,[{eol, eol()}]}]);
 init([Level,false]) -> % for backwards compatibility
-    init([Level,{lager_default_formatter,?TERSE_FORMAT}]);
+    init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]);
 init([Level,{Formatter,FormatterConfig}]) when is_atom(Formatter) ->
-   try lager_util:config_to_mask(Level) of
+    Colors = case application:get_env(lager, colored) of
+        {ok, true} -> 
+            {ok, LagerColors} = application:get_env(lager, colors),
+            LagerColors;
+        _ -> []
+    end,
+
+    try lager_util:config_to_mask(Level) of
         Levels ->
             {ok, #state{level=Levels,
                     formatter=Formatter, 
-                    format_config=FormatterConfig}}
+                    format_config=FormatterConfig,
+                    colors=Colors}}
     catch
         _:_ ->
             {error, bad_log_level}
     end;
 init(Level) ->
-    init([Level,{lager_default_formatter,?TERSE_FORMAT}]).
+    init([Level,{lager_default_formatter,?TERSE_FORMAT ++ [eol()]}]).
 
 
 %% @private
@@ -70,10 +77,10 @@
 
 %% @private
 handle_event({log, Message},
-    #state{level=L,formatter=Formatter,format_config=FormatConfig} = State) ->
+    #state{level=L,formatter=Formatter,format_config=FormatConfig,colors=Colors} = State) ->
     case lager_util:is_loggable(Message, L, ?MODULE) of
         true ->
-            io:put_chars(user, Formatter:format(Message,FormatConfig)),
+            io:put_chars(user, Formatter:format(Message,FormatConfig,Colors)),
             {ok, State};
         false ->
             {ok, State}
@@ -93,6 +100,14 @@
 code_change(_OldVsn, State, _Extra) ->
     {ok, State}.
 
+eol() ->
+    case application:get_env(lager, colored) of
+        {ok, true}  ->
+            "\e[0m\r\n";
+        _ -> 
+            "\r\n"
+    end.
+
 -ifdef(TEST).
 console_log_test_() ->
     %% tiny recursive fun that pretends to be a group leader
@@ -131,16 +146,17 @@
             {"regular console logging",
                 fun() ->
                         Pid = spawn(F(self())),
-                        gen_event:add_handler(lager_event, lager_console_backend, info),
                         unregister(user),
                         register(user, Pid),
                         erlang:group_leader(Pid, whereis(lager_event)),
+                        gen_event:add_handler(lager_event, lager_console_backend, info),
                         lager_config:set(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
                         lager:log(info, self(), "Test message"),
                         receive
                             {io_request, From, ReplyAs, {put_chars, unicode, Msg}} ->
                                 From ! {io_reply, ReplyAs, ok},
-                                ?assertMatch([_, "[info]", "Test message\r\n"], re:split(Msg, " ", [{return, list}, {parts, 3}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, "[info]", TestMsg], re:split(Msg, " ", [{return, list}, {parts, 3}]))
                         after
                             500 ->
                                 ?assert(false)
@@ -156,11 +172,11 @@
                         gen_event:add_handler(lager_event, lager_console_backend, [info, true]),
                         lager_config:set(loglevel, {element(2, lager_util:config_to_mask(info)), []}),
                         lager:info("Test message"),
-                        lager:info("Test message"),
                         PidStr = pid_to_list(self()),
                         receive
                             {io_request, _, _, {put_chars, unicode, Msg}} ->
-                                ?assertMatch([_, _, "[info]", PidStr, _,"Test message\r\n"], re:split(Msg, "[ @]", [{return, list}, {parts, 6}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, _, "[info]", PidStr, _, TestMsg], re:split(Msg, "[ @]", [{return, list}, {parts, 6}]))
                         after
                             500 ->
                                 ?assert(false)
@@ -183,7 +199,8 @@
                         ModuleStr = atom_to_list(?MODULE),
                         receive
                             {io_request, _, _, {put_chars, unicode, Msg}} ->
-                                ?assertMatch([_, _, "info", NodeStr, PidStr, ModuleStr, _, _, _, "Test message\r\n"], 
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, _, "info", NodeStr, PidStr, ModuleStr, _, _, _, TestMsg], 
                                              re:split(Msg, "#", [{return, list}, {parts, 10}]))
                         after
                             500 ->
@@ -213,7 +230,8 @@
                         receive
                             {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
                                 From1 ! {io_reply, ReplyAs1, ok},
-                                ?assertMatch([_, "[debug]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, "[debug]", TestMsg], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
                         after
                             500 ->
                                 ?assert(false)
@@ -242,7 +260,8 @@
                         receive
                             {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
                                 From1 ! {io_reply, ReplyAs1, ok},
-                                ?assertMatch([_, "[error]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, "[error]", TestMsg], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
                         after
                             1000 ->
                                 ?assert(false)
@@ -271,7 +290,8 @@
                         receive
                             {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
                                 From1 ! {io_reply, ReplyAs1, ok},
-                                ?assertMatch([_, "[debug]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, "[debug]", TestMsg], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
                         after
                             1000 ->
                                 ?assert(false)
@@ -301,7 +321,8 @@
                         receive
                             {io_request, From1, ReplyAs1, {put_chars, unicode, Msg1}} ->
                                 From1 ! {io_reply, ReplyAs1, ok},
-                                ?assertMatch([_, "[debug]", "Test message\r\n"], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
+                                TestMsg = "Test message" ++ eol(),
+                                ?assertMatch([_, "[debug]", TestMsg], re:split(Msg1, " ", [{return, list}, {parts, 3}]))
                         after
                             1000 ->
                                 ?assert(false)
diff --git a/src/lager_default_formatter.erl b/src/lager_default_formatter.erl
index cbe614f..e061b7e 100644
--- a/src/lager_default_formatter.erl
+++ b/src/lager_default_formatter.erl
@@ -27,7 +27,7 @@
 %%
 %% Exported Functions
 %%
--export([format/2]).
+-export([format/2, format/3]).
 
 %%
 %% API Functions
@@ -53,22 +53,28 @@
 %%
 %%    `[{pid, ["My pid is ", pid], "Unknown Pid"}]' -> if pid is in the metada print "My pid is ?.?.?", otherwise print "Unknown Pid"
 %% @end
--spec format(lager_msg:lager_msg(),list()) -> any().
-format(Msg,[]) ->
-    format(Msg, [{eol, "\n"}]);
-format(Msg,[{eol, EOL}]) ->
+-spec format(lager_msg:lager_msg(),list(),list()) -> any().
+format(Msg,[], Colors) ->
+    format(Msg, [{eol, "\n"}], Colors);
+format(Msg,[{eol, EOL}], Colors) ->
     format(Msg,
-        [date, " ", time, " [", severity, "] ",
+        [date, " ", time, " ", color, "[", severity, "] ",
             {pid, ""},
             {module, [
                     {pid, ["@"], ""},
                     module,
                     {function, [":", function], ""},
                     {line, [":",line], ""}], ""},
-            " ", message, EOL]);
-format(Message,Config) ->
-    [ output(V,Message) || V <- Config ].
+            " ", message, EOL], Colors);
+format(Message,Config,Colors) ->
+    [ case V of
+        color -> output_color(Message,Colors);
+        _ -> output(V,Message) 
+      end || V <- Config ].
 
+-spec format(lager_msg:lager_msg(),list()) -> any().
+format(Msg, Config) ->
+    format(Msg, Config, []).
 
 -spec output(term(),lager_msg:lager_msg()) -> iolist().
 output(message,Msg) -> lager_msg:message(Msg);
@@ -97,6 +103,14 @@
     end;
 output(Other,_) -> make_printable(Other).
 
+output_color(_Msg,[]) -> [];
+output_color(Msg,Colors) ->
+    Level = lager_msg:severity(Msg),
+    case lists:keyfind(Level, 1, Colors) of
+        {_, Color} -> Color;
+        _ -> []
+    end.
+
 -spec make_printable(any()) -> iolist().
 make_printable(A) when is_atom(A) -> atom_to_list(A);
 make_printable(P) when is_pid(P) -> pid_to_list(P);