Просмотр исходного кода

fix(json trace format): use best_effort_json instead of new encoder

Kjell Winblad 1 год назад
Родитель
Сommit
968dc2ccda

+ 0 - 3
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}) ->

+ 31 - 64
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).