Packages

A custom erlang logger formatter which prints JSON

Current section

Files

Jump to
erlang_json_logger src erlang_json_logger.erl
Raw

src/erlang_json_logger.erl

-module(erlang_json_logger).
%% logger callbacks
-export([ format/2 ]).
-ifdef(TEST).
-export([ format_msg/3 ]).
-export([ pre_encode/1 ]).
-endif.
%% -- logger callbacks
-spec format(LogEvent, Config) -> unicode:chardata() when
LogEvent :: logger:log_event(),
Config :: logger:formatter_config().
format(#{level:=Level, msg:={report, Msg}, meta:=Meta}, Config) when is_map(Msg) ->
Meta0 = maps:put(level, Level, Meta),
format_msg(Msg, Meta0, Config);
format(Map = #{msg := {report, KeyVal}}, Config) when is_list(KeyVal) ->
format(Map#{msg := {report, maps:from_list(KeyVal)}}, Config);
format(Map = #{msg := {string, String}}, Config) ->
Msg = #{text => unicode:characters_to_binary(String)},
format(Map#{msg := {report, Msg}}, Config);
format(Map = #{msg := {Format, Terms}}, Config) ->
String = unicode:characters_to_binary(io_lib:format(Format, Terms)),
Msg = #{text => String},
format(Map#{msg := {report, Msg}}, Config).
%% -- private
format_msg(Msg, Meta, Config) when
is_map(Msg) andalso
is_map(Meta) andalso
is_map(Config) ->
Defaults = #{ indent => 2 },
Config0 = maps:merge(Defaults, Config),
Msg0 = maps:merge(Msg, Meta),
encode(Msg0, Config0).
%% --
encode(Map, Config) ->
jsx:encode(maps:to_list(Map),
maps:to_list(Config)++[{pre_encode, fun pre_encode/1}]).
pre_encode(Pid) when is_pid(Pid) ->
list_to_binary(pid_to_list(Pid));
pre_encode([{Pid1, Pid2} | Rest]) when is_pid(Pid1), is_pid(Pid2) ->
[{pre_encode(Pid1), pre_encode(Pid2)} | pre_encode(Rest)];
pre_encode([{Pid, Other} | Rest]) when is_pid(Pid) ->
[{pre_encode(Pid), Other} | pre_encode(Rest)];
pre_encode(Other) ->
Other.