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

fix(oracle action trace): parameters should not be rendered as IO Data

This forces the parameters to the database statement to be rendered as
a JSON array in JSON traces instead of being rendered as a string when
the parameters are interpreted as IO data.

Fixes:
https://emqx.atlassian.net/browse/EMQX-12433
Kjell Winblad 1 год назад
Родитель
Сommit
f65168982b
2 измененных файлов с 43 добавлено и 1 удалено
  1. 32 0
      apps/emqx/src/emqx_logger_jsonfmt.erl
  2. 11 1
      apps/emqx_oracle/src/emqx_oracle.erl

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

@@ -270,6 +270,8 @@ json(L, Config) when is_list(L) ->
     end;
 json(Map, Config) when is_map(Map) ->
     best_effort_json_obj(Map, Config);
+json({'$array$', List}, Config) when is_list(List) ->
+    [json(I, Config) || I <- List];
 json(Term, Config) ->
     do_format_msg("~p", [Term], Config).
 
@@ -448,6 +450,36 @@ best_effort_json_test() ->
         <<"[\n  {\n    \"key\" : [\n      \n    ]\n  }\n]">>,
         best_effort_json([#{key => []}])
     ),
+    %% List is IO Data
+    ?assertMatch(
+        #{<<"what">> => <<"hej\n">>},
+        emqx_utils_json:decode(emqx_logger_jsonfmt:best_effort_json(#{what => [<<"hej">>, 10]}))
+    ),
+    %% Force list to be interpreted as an array
+    ?assertMatch(
+        #{<<"what">> => [<<"hej">>, 10]},
+        emqx_utils_json:decode(
+            emqx_logger_jsonfmt:best_effort_json(#{what => {'$array$', [<<"hej">>, 10]}})
+        )
+    ),
+    %% IO Data inside an array
+    ?assertMatch(
+        #{<<"what">> => [<<"hej">>, 10, <<"hej\n">>]},
+        emqx_utils_json:decode(
+            emqx_logger_jsonfmt:best_effort_json(#{
+                what => {'$array$', [<<"hej">>, 10, [<<"hej">>, 10]]}
+            })
+        )
+    ),
+    %% Array inside an array
+    ?assertMatch(
+        #{<<"what">> => [<<"hej">>, 10, [<<"hej">>, 10]]},
+        emqx_utils_json:decode(
+            emqx_logger_jsonfmt:best_effort_json(#{
+                what => {'$array$', [<<"hej">>, 10, {'$array$', [<<"hej">>, 10]}]}
+            })
+        )
+    ),
     ok.
 
 config() ->

+ 11 - 1
apps/emqx_oracle/src/emqx_oracle.erl

@@ -8,6 +8,7 @@
 
 -include_lib("emqx_resource/include/emqx_resource.hrl").
 -include_lib("emqx/include/logger.hrl").
+-include_lib("emqx/include/emqx_trace.hrl").
 -include_lib("snabbkaffe/include/snabbkaffe.hrl").
 
 -define(UNHEALTHY_TARGET_MSG,
@@ -288,7 +289,7 @@ on_sql_query(InstId, ChannelID, PoolName, Type, ApplyMode, NameOrSQL, Data) ->
         type => Type,
         apply_mode => ApplyMode,
         name_or_sql => NameOrSQL,
-        data => Data
+        data => #emqx_trace_format_func_data{function = fun trace_format_data/1, data = Data}
     }),
     case ecpool:pick_and_do(PoolName, {?MODULE, Type, [NameOrSQL, Data]}, ApplyMode) of
         {error, Reason} = Result ->
@@ -317,6 +318,15 @@ on_sql_query(InstId, ChannelID, PoolName, Type, ApplyMode, NameOrSQL, Data) ->
             Result
     end.
 
+trace_format_data(Data0) ->
+    %% In batch request, we get a two level list
+    {'$array$', lists:map(fun insert_array_marker_if_list/1, Data0)}.
+
+insert_array_marker_if_list(List) when is_list(List) ->
+    {'$array$', List};
+insert_array_marker_if_list(Item) ->
+    Item.
+
 on_get_status(_InstId, #{pool_name := Pool} = _State) ->
     case emqx_resource_pool:health_check_workers(Pool, fun ?MODULE:do_get_status/1) of
         true ->