Current section

Files

Jump to
lager_json_formatter src lager_json_formatter.erl
Raw

src/lager_json_formatter.erl

-module(lager_json_formatter).
-include_lib("lager/include/lager.hrl").
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
-export([format/2, format/3]).
-define(DEFAULT_CONFIG, [{date, [date, " ", time]},
message,
pid,
severity,
{component, [{module, "-"}, ":", {function, "-"}, "/", {line, "-"}]}]).
-spec format(lager_msg:lager_msg(), list(), list()) -> any().
format(Message, Config, _Colors) -> format(Message, Config).
-spec format(lager_msg:lager_msg(), list()) -> any().
format(Message, []) ->
format(Message, ?DEFAULT_CONFIG);
format(Message, Config) ->
Map = lists:foldl(fun(Data, Map) ->
output(Data, Map, Message)
end, #{}, Config),
<< (jsx:encode(Map))/binary, "\n" >>.
output(Data, Map, Message) when is_atom(Data) ->
maps:put(Data, get_data(Data, Message), Map);
output({Key, Value}, Map, Message) when is_list(Value) ->
maps:put(Key, to_binary([get_data(V, Message) || V <- Value]), Map);
output({Key, Value}, Map, Message) ->
maps:put(Key, get_data(Value, Message), Map).
get_data(Value, _) when is_list(Value); is_binary(Value) ->
Value;
get_data(message, Message) ->
to_binary(lager_msg:message(Message));
get_data(date, Message) ->
{D, _} = lager_msg:datetime(Message),
to_binary(D);
get_data(time, Message) ->
{_, T} = lager_msg:datetime(Message),
to_binary(T);
get_data(severity, Message) ->
atom_to_binary(lager_msg:severity(Message), latin1);
get_data({Metadata, Absent}, Message) ->
MD = lager_msg:metadata(Message),
case lists:keyfind(Metadata, 1, MD) of
false ->
Absent;
{Metadata, Value} ->
to_binary(Value)
end;
get_data(Metadata, Message) when is_atom(Metadata) ->
get_data({Metadata, <<"Undefined">>}, Message).
to_binary(A) when is_atom(A) -> atom_to_binary(A, latin1);
to_binary(P) when is_pid(P) -> list_to_binary(pid_to_list(P));
to_binary([L]) when is_list(L) -> iolist_to_binary(L);
to_binary(L) when is_list(L) -> iolist_to_binary(L);
to_binary(B) when is_binary(B) -> B;
to_binary(O) -> list_to_binary(io_lib:format("~p", [O])).
-ifdef(TEST).
format_test() ->
Msg = lager_msg:new("hello", {1465, 900000, 0}, info,
[{pid, c:pid(0, 0, 0)},
{module, ?MODULE},
{function, test},
{line, 123}],
[]),
?assertEqual(<<"{\"component\":\"lager_json_formatter:test/123\","
"\"date\":\"2016-06-14 12:26:40.000\","
"\"message\":\"hello\","
"\"pid\":\"<0.0.0>\","
"\"severity\":\"info\"}\n">>,
format(Msg, [])),
?assertEqual(<<"{\"datetime\":\"2016-06-14-12:26:40.000\","
"\"msg\":\"hello\","
"\"sev\":\"info\"}\n">>,
format(Msg, [{datetime, [date, "-", time]},
{msg, message},
{sev, severity}])).
special_chars_test() ->
Msg = lager_msg:new("hello\r\n\t\"wor\\d!", {1465, 900000, 0}, info,
[],
[]),
?assertEqual(<<"{\"component\":\"-:-/-\","
"\"date\":\"2016-06-14 12:26:40.000\","
"\"message\":\"hello\\r\\n\\t\\\"wor\\\\d!\","
"\"pid\":\"Undefined\","
"\"severity\":\"info\"}\n">>,
format(Msg, [])).
-endif.