diff --git a/README.md b/README.md index 48e0c70..8eaec57 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,15 @@ To print each json object to a new line, set `new_line` to `true`: #{formatter => {jsonformat, #{ new_line => true }}} ``` +To control what is being included in the log object from the metadata, there +are two ways. One can opt-out from fields. Default opts out is `[report_cb]`. + + #{ meta_without => [report_cb, gl, file, domain] } + +Or for very detailed control there is instead opt-in. + + #{ meta_with => [time, mfa, line, user_key, client_key] } + To rename keys in the resulting json object, provide a `key_mapping`. For example, to rename the `time` and `level` keys to `timestamp` and `lvl` respectively, use: diff --git a/src/jsonformat.erl b/src/jsonformat.erl index 8994544..a444206 100644 --- a/src/jsonformat.erl +++ b/src/jsonformat.erl @@ -43,7 +43,7 @@ format(#{msg:={report, #{format:=Format, args:=Args, label:={error_logger, _}}}} Report = #{text => io_lib:format(Format, Args)}, format(Map#{msg := {report, Report}}, Config); format(#{level:=Level, msg:={report, Msg}, meta:=Meta}, Config) when is_map(Msg) -> - Data0 = maps:merge(Msg, Meta#{level => Level}), + Data0 = merge_meta(Msg, Meta#{level => Level}, Config), Data1 = apply_key_mapping(Data0, Config), Data2 = apply_format_funs(Data1, Config), encode(pre_encode(Data2, Config), Config); @@ -75,6 +75,11 @@ pre_encode(Data, Config) -> maps:new(), Data). +merge_meta(Msg, Meta0, Config) -> + Meta1 = meta_without(Meta0, Config), + Meta2 = meta_with(Meta1, Config), + maps:merge(Msg, Meta2). + encode(Data, Config) -> Json = jsx:encode(Data), case new_line(Config) of @@ -121,6 +126,15 @@ apply_key_mapping(Data, _) -> new_line(Config) -> maps:get(new_line, Config, ?NEW_LINE). +meta_without(Meta, Config) -> + maps:without(maps:get(meta_without, Config, [report_cb]), Meta). + +meta_with(Meta, #{ meta_with := Ks}) -> + maps:with(Ks, Meta); +meta_with(Meta, _ConfigNotPresent) -> + Meta. + + %%%_* Tests ============================================================ -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -171,6 +185,38 @@ list_format_test() -> ?assertEqual( <<"{\"level\":\"error\",\"report\":\"[{hej,\\\"hopp\\\"}]\",\"time\":1}">> , format(ErrorReport, #{})). +meta_without_test() -> + Error = #{ level => info + , msg => {report, #{answer => 42}} + , meta => #{secret => xyz}}, + ?assertEqual([ {<<"answer">>, 42} + , {<<"level">>, <<"info">>} + , {<<"secret">>, <<"xyz">>} + ], + jsx:decode(format(Error, #{}))), + Config2 = #{ meta_without => [secret]}, + ?assertEqual([ {<<"answer">>, 42} + , {<<"level">>, <<"info">>} + ], + jsx:decode(format(Error, Config2))), + ok. + +meta_with_test() -> + Error = #{ level => info + , msg => {report, #{answer => 42}} + , meta => #{secret => xyz}}, + ?assertEqual([ {<<"answer">>, 42} + , {<<"level">>, <<"info">>} + , {<<"secret">>, <<"xyz">>} + ], + jsx:decode(format(Error, #{}))), + Config2 = #{ meta_with => [level]}, + ?assertEqual([ {<<"answer">>, 42} + , {<<"level">>, <<"info">>} + ], + jsx:decode(format(Error, Config2))), + ok. + -endif. %%%_* Emacs ============================================================