فهرست منبع

fix(best_effort_json): only do tuple list to map without losing pairs

Kjell Winblad 1 سال پیش
والد
کامیت
9fd8e930be
2فایلهای تغییر یافته به همراه40 افزوده شده و 0 حذف شده
  1. 11 0
      apps/emqx/src/emqx_logger_jsonfmt.erl
  2. 29 0
      apps/emqx_management/test/emqx_mgmt_api_trace_SUITE.erl

+ 11 - 0
apps/emqx/src/emqx_logger_jsonfmt.erl

@@ -219,6 +219,8 @@ best_effort_unicode(Input, Config) ->
 
 best_effort_json_obj(List, Config) when is_list(List) ->
     try
+        %% We should only do this if there are no duplicated keys
+        check_no_dup_tuple_list(List),
         json_obj(maps:from_list(List), Config)
     catch
         _:_ ->
@@ -232,6 +234,15 @@ best_effort_json_obj(Map, Config) ->
             do_format_msg("~p", [Map], Config)
     end.
 
+check_no_dup_tuple_list(List) ->
+    %% Crash if this is not a tuple list
+    lists:foreach(fun({_, _}) -> ok end, List),
+    Items = [K || {K, _} <- List],
+    NumberOfItems = length(Items),
+    %% Crash if there are duplicates
+    NumberOfItems = maps:size(maps:from_keys(Items, true)),
+    ok.
+
 json(A, _) when is_atom(A) -> A;
 json(I, _) when is_integer(I) -> I;
 json(F, _) when is_float(F) -> F;

+ 29 - 0
apps/emqx_management/test/emqx_mgmt_api_trace_SUITE.erl

@@ -271,6 +271,16 @@ t_http_test_json_formatter(_Config) ->
     }),
     %% We should handle report style logging
     ?SLOG(error, #{msg => "recursive_republish_detected"}, #{topic => Topic}),
+    ?TRACE("CUSTOM", "my_log_msg", #{
+        topic => Topic,
+        %% This will be converted to map
+        map_key => [{a, a}, {b, b}]
+    }),
+    ?TRACE("CUSTOM", "my_log_msg", #{
+        topic => Topic,
+        %% We should not convert this to a map as we will lose information
+        map_key => [{a, a}, {a, b}]
+    }),
     ok = emqx_trace_handler_SUITE:filesync(Name, topic),
     {ok, _Detail2} = request_api(get, api_path("trace/" ++ binary_to_list(Name) ++ "/log_detail")),
     {ok, Bin} = request_api(get, api_path("trace/" ++ binary_to_list(Name) ++ "/download")),
@@ -425,6 +435,25 @@ t_http_test_json_formatter(_Config) ->
         },
         NextFun()
     ),
+    ?assertMatch(
+        #{
+            <<"meta">> := #{
+                <<"map_key">> := #{
+                    <<"a">> := <<"a">>,
+                    <<"b">> := <<"b">>
+                }
+            }
+        },
+        NextFun()
+    ),
+    ?assertMatch(
+        #{
+            <<"meta">> := #{
+                <<"map_key">> := [_, _]
+            }
+        },
+        NextFun()
+    ),
     {ok, Delete} = request_api(delete, api_path("trace/" ++ binary_to_list(Name))),
     ?assertEqual(<<>>, Delete),