diff --git a/apps/emqx/src/emqx_trace/emqx_trace_handler.erl b/apps/emqx/src/emqx_trace/emqx_trace_handler.erl index 169e0361b..c0172b2dc 100644 --- a/apps/emqx/src/emqx_trace/emqx_trace_handler.erl +++ b/apps/emqx/src/emqx_trace/emqx_trace_handler.erl @@ -199,9 +199,6 @@ filters(#{type := ruleid, filter := Filter, name := Name}) -> formatter(#{type := _Type, payload_encode := PayloadEncode, formatter := json}) -> {emqx_trace_json_formatter, #{ - single_line => true, - max_size => unlimited, - depth => unlimited, payload_encode => PayloadEncode }}; formatter(#{type := _Type, payload_encode := PayloadEncode}) -> diff --git a/apps/emqx/src/emqx_trace/emqx_trace_json_formatter.erl b/apps/emqx/src/emqx_trace/emqx_trace_json_formatter.erl index 6f30774a6..c6d4761ea 100644 --- a/apps/emqx/src/emqx_trace/emqx_trace_json_formatter.erl +++ b/apps/emqx/src/emqx_trace/emqx_trace_json_formatter.erl @@ -33,78 +33,45 @@ format( LogMap, #{payload_encode := PEncode} ) -> + %% We just make some basic transformations on the input LogMap and then do + %% an external call to create the JSON text Time = emqx_utils_calendar:now_to_rfc3339(microsecond), LogMap1 = LogMap#{time => Time}, - [format_log_map(LogMap1, PEncode), "\n"]. + LogMap2 = prepare_log_map(LogMap1, PEncode), + [emqx_logger_jsonfmt:best_effort_json(LogMap2, [force_utf8]), "\n"]. %%%----------------------------------------------------------------- %%% Helper Functions %%%----------------------------------------------------------------- -format_log_map(Map, PEncode) -> - KeyValuePairs = format_key_value_pairs(maps:to_list(Map), PEncode, []), - ["{", KeyValuePairs, "}"]. +prepare_log_map(LogMap, PEncode) when is_map(LogMap) -> + NewKeyValuePairs = [prepare_key_value(K, V, PEncode) || {K, V} <- maps:to_list(LogMap)], + maps:from_list(NewKeyValuePairs); +prepare_log_map(Term, _PEncode) -> + Term. -format_key_value_pairs([], _PEncode, Acc) -> - lists:join(",", Acc); -format_key_value_pairs([{payload, Value} | Rest], PEncode, Acc) -> - FormattedPayload = format_payload(Value, PEncode), - FormattedPayloadEscaped = escape(FormattedPayload), - Pair = ["\"payload\": \"", FormattedPayloadEscaped, "\""], - format_key_value_pairs(Rest, PEncode, [Pair | Acc]); -format_key_value_pairs([{packet, Value} | Rest], PEncode, Acc) -> - Formatted = format_packet(Value, PEncode), - FormattedEscaped = escape(Formatted), - Pair = ["\"packet\": \"", FormattedEscaped, "\""], - format_key_value_pairs(Rest, PEncode, [Pair | Acc]); -format_key_value_pairs([{Key, Value} | Rest], PEncode, Acc) -> - FormattedKey = format_key(Key), - FormattedValue = format_value(Value, PEncode), - Pair = ["\"", FormattedKey, "\":", FormattedValue], - format_key_value_pairs(Rest, PEncode, [Pair | Acc]). - -format_key(Term) -> - %% Keys must be strings - String = try_format_unicode(Term), - escape(String). - -format_value(Map, PEncode) when is_map(Map) -> - format_log_map(Map, PEncode); -format_value(V, _PEncode) when is_integer(V) -> - integer_to_list(V); -format_value(V, _PEncode) when is_float(V) -> - float_to_list(V, [{decimals, 2}]); -format_value(true, _PEncode) -> - "true"; -format_value(false, _PEncode) -> - "false"; -format_value(V, _PEncode) -> - String = try_format_unicode(V), - ["\"", escape(String), "\""]. - -try_format_unicode(undefined) -> - %% emqx_logger_textfmt:try_format_unicode converts the atom undefined to - %% the atom undefined - "undefined"; -try_format_unicode(V) -> - emqx_logger_textfmt:try_format_unicode(V). - -escape(IOList) -> - Bin = iolist_to_binary(IOList), - List = binary_to_list(Bin), - escape_list(List). - -escape_list([]) -> - []; -escape_list([$\n | Rest]) -> - %% 92 is backslash - [92, $n | escape_list(Rest)]; -escape_list([$" | Rest]) -> - [92, $" | escape_list(Rest)]; -escape_list([92 | Rest]) -> - [92, 92 | escape_list(Rest)]; -escape_list([X | Rest]) -> - [X | escape_list(Rest)]. +prepare_key_value(payload = K, V, PEncode) -> + NewV = + try + format_payload(V, PEncode) + catch + _:_:_ -> + V + end, + {K, NewV}; +prepare_key_value(packet = K, V, PEncode) -> + NewV = + try + format_packet(V, PEncode) + catch + _:_:_ -> + V + end, + {K, NewV}; +prepare_key_value(K, V, PEncode) when is_map(V) -> + {K, prepare_log_map(V, PEncode)}; +prepare_key_value(K, V, _PEncode) -> + {K, V}. format_packet(undefined, _) -> ""; format_packet(Packet, Encode) -> emqx_packet:format(Packet, Encode).