diff --git a/apps/emqx/src/emqx_logger_jsonfmt.erl b/apps/emqx/src/emqx_logger_jsonfmt.erl index 7405e638b..c6c04f70d 100644 --- a/apps/emqx/src/emqx_logger_jsonfmt.erl +++ b/apps/emqx/src/emqx_logger_jsonfmt.erl @@ -236,20 +236,24 @@ json(P, C) when is_port(P) -> json(port_to_list(P), C); json(F, C) when is_function(F) -> json(erlang:fun_to_list(F), C); json(B, Config) when is_binary(B) -> best_effort_unicode(B, Config); -json(L, Config) when is_list(L), is_integer(hd(L)) -> - best_effort_unicode(L, Config); json(M, Config) when is_list(M), is_tuple(hd(M)), tuple_size(hd(M)) =:= 2 -> best_effort_json_obj(M, Config); json(L, Config) when is_list(L) -> - [json(I, Config) || I <- L]; + try unicode:characters_to_binary(L, utf8) of + B when is_binary(B) -> B; + _ -> [json(I, Config) || I <- L] + catch + _:_ -> + [json(I, Config) || I <- L] + end; json(Map, Config) when is_map(Map) -> best_effort_json_obj(Map, Config); json(Term, Config) -> do_format_msg("~p", [Term], Config). json_obj_root(Data0, Config) -> - Time = maps:get(time, Data0), - Level = maps:get(level, Data0), + Time = maps:get(time, Data0, undefined), + Level = maps:get(level, Data0, undefined), Msg1 = case maps:get(msg, Data0, undefined) of undefined -> @@ -264,28 +268,7 @@ json_obj_root(Data0, Config) -> _ -> json(Msg1, Config) end, - Line = - case maps:get(line, Data0, undefined) of - undefined -> - <<"">>; - Num -> - iolist_to_binary([":", integer_to_list(Num)]) - end, - - Mfal = - case maps:get(mfa, Data0, undefined) of - {M, F, A} -> - << - (atom_to_binary(M, utf8))/binary, - $:, - (atom_to_binary(F, utf8))/binary, - $/, - (integer_to_binary(A))/binary, - Line/binary - >>; - _ -> - unefined - end, + Mfal = emqx_utils:format_mfal(Data0), Data = maps:fold( fun(K, V, D) -> @@ -293,7 +276,9 @@ json_obj_root(Data0, Config) -> [{K1, V1} | D] end, [], - maps:without([time, gl, file, report_cb, msg, '$kind', mfa, level, line], Data0) + maps:without( + [time, gl, file, report_cb, msg, '$kind', mfa, level, line, is_trace], Data0 + ) ), lists:filter( fun({_, V}) -> V =/= undefined end, diff --git a/apps/emqx/src/emqx_logger_textfmt.erl b/apps/emqx/src/emqx_logger_textfmt.erl index 3dce8a2ec..2e8718c37 100644 --- a/apps/emqx/src/emqx_logger_textfmt.erl +++ b/apps/emqx/src/emqx_logger_textfmt.erl @@ -56,8 +56,7 @@ enrich_report(ReportRaw, Meta) -> end, ClientId = maps:get(clientid, Meta, undefined), Peer = maps:get(peername, Meta, undefined), - MFA = maps:get(mfa, Meta, undefined), - Line = maps:get(line, Meta, undefined), + MFA = emqx_utils:format_mfal(Meta), Msg = maps:get(msg, ReportRaw, undefined), %% turn it into a list so that the order of the fields is determined lists:foldl( @@ -70,8 +69,7 @@ enrich_report(ReportRaw, Meta) -> {topic, try_format_unicode(Topic)}, {clientid, try_format_unicode(ClientId)}, {peername, Peer}, - {line, Line}, - {mfa, mfa(MFA)}, + {mfa, try_format_unicode(MFA)}, {msg, Msg} ] ). @@ -84,7 +82,7 @@ try_format_unicode(Char) -> case unicode:characters_to_list(Char) of {error, _, _} -> error; {incomplete, _, _} -> error; - Binary -> Binary + List1 -> List1 end catch _:_ -> @@ -95,8 +93,8 @@ try_format_unicode(Char) -> _ -> List end. -enrich_mfa({Fmt, Args}, #{mfa := Mfa, line := Line}) when is_list(Fmt) -> - {Fmt ++ " mfa: ~ts line: ~w", Args ++ [mfa(Mfa), Line]}; +enrich_mfa({Fmt, Args}, Data) when is_list(Fmt) -> + {Fmt ++ " mfa: ~ts", Args ++ [emqx_utils:format_mfal(Data)]}; enrich_mfa(Msg, _) -> Msg. @@ -113,6 +111,3 @@ enrich_topic({Fmt, Args}, #{topic := Topic}) when is_list(Fmt) -> {" topic: ~ts" ++ Fmt, [Topic | Args]}; enrich_topic(Msg, _) -> Msg. - -mfa(undefined) -> undefined; -mfa({M, F, A}) -> [atom_to_list(M), ":", atom_to_list(F), "/" ++ integer_to_list(A)]. diff --git a/apps/emqx_utils/src/emqx_utils.erl b/apps/emqx_utils/src/emqx_utils.erl index e21affce6..0682a9b4d 100644 --- a/apps/emqx_utils/src/emqx_utils.erl +++ b/apps/emqx_utils/src/emqx_utils.erl @@ -61,7 +61,8 @@ diff_lists/3, merge_lists/3, tcp_keepalive_opts/4, - format/1 + format/1, + format_mfal/1 ]). -export([ @@ -529,6 +530,30 @@ tcp_keepalive_opts(OS, _Idle, _Interval, _Probes) -> format(Term) -> iolist_to_binary(io_lib:format("~0p", [Term])). +%% @doc Helper function for log formatters. +-spec format_mfal(map()) -> undefined | binary(). +format_mfal(Data) -> + Line = + case maps:get(line, Data, undefined) of + undefined -> + <<"">>; + Num -> + ["(", integer_to_list(Num), ")"] + end, + case maps:get(mfa, Data, undefined) of + {M, F, A} -> + iolist_to_binary([ + atom_to_binary(M, utf8), + $:, + atom_to_binary(F, utf8), + $/, + integer_to_binary(A), + Line + ]); + _ -> + undefined + end. + %%------------------------------------------------------------------------------ %% Internal Functions %%------------------------------------------------------------------------------ diff --git a/rel/i18n/emqx_conf_schema.hocon b/rel/i18n/emqx_conf_schema.hocon index 674eeddd5..e26a21fa0 100644 --- a/rel/i18n/emqx_conf_schema.hocon +++ b/rel/i18n/emqx_conf_schema.hocon @@ -661,7 +661,7 @@ Can be one of: - utc: the UTC time offset - +-[hh]:[mm]: user specified time offset, such as "-02:00" or "+00:00" Defaults to: system. -This config has no effect for when formatter is 'json' as the timestamp in JSON is miliseconds since epoch.""" +This config has no effect for when formatter is 'json' as the timestamp in JSON is milliseconds since epoch.""" common_handler_time_offset.label: """Time Offset"""