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
This commit is contained in:
Kjell Winblad 2024-05-28 06:02:31 +02:00
parent 02d10a2023
commit f65168982b
2 changed files with 43 additions and 1 deletions

View File

@ -270,6 +270,8 @@ json(L, Config) when is_list(L) ->
end; end;
json(Map, Config) when is_map(Map) -> json(Map, Config) when is_map(Map) ->
best_effort_json_obj(Map, Config); best_effort_json_obj(Map, Config);
json({'$array$', List}, Config) when is_list(List) ->
[json(I, Config) || I <- List];
json(Term, Config) -> json(Term, Config) ->
do_format_msg("~p", [Term], Config). do_format_msg("~p", [Term], Config).
@ -448,6 +450,36 @@ best_effort_json_test() ->
<<"[\n {\n \"key\" : [\n \n ]\n }\n]">>, <<"[\n {\n \"key\" : [\n \n ]\n }\n]">>,
best_effort_json([#{key => []}]) 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. ok.
config() -> config() ->

View File

@ -8,6 +8,7 @@
-include_lib("emqx_resource/include/emqx_resource.hrl"). -include_lib("emqx_resource/include/emqx_resource.hrl").
-include_lib("emqx/include/logger.hrl"). -include_lib("emqx/include/logger.hrl").
-include_lib("emqx/include/emqx_trace.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl"). -include_lib("snabbkaffe/include/snabbkaffe.hrl").
-define(UNHEALTHY_TARGET_MSG, -define(UNHEALTHY_TARGET_MSG,
@ -288,7 +289,7 @@ on_sql_query(InstId, ChannelID, PoolName, Type, ApplyMode, NameOrSQL, Data) ->
type => Type, type => Type,
apply_mode => ApplyMode, apply_mode => ApplyMode,
name_or_sql => NameOrSQL, 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 case ecpool:pick_and_do(PoolName, {?MODULE, Type, [NameOrSQL, Data]}, ApplyMode) of
{error, Reason} = Result -> {error, Reason} = Result ->
@ -317,6 +318,15 @@ on_sql_query(InstId, ChannelID, PoolName, Type, ApplyMode, NameOrSQL, Data) ->
Result Result
end. 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) -> on_get_status(_InstId, #{pool_name := Pool} = _State) ->
case emqx_resource_pool:health_check_workers(Pool, fun ?MODULE:do_get_status/1) of case emqx_resource_pool:health_check_workers(Pool, fun ?MODULE:do_get_status/1) of
true -> true ->