diff --git a/apps/emqx/src/emqx_map_lib.erl b/apps/emqx/src/emqx_map_lib.erl index d666e315e..650ef0401 100644 --- a/apps/emqx/src/emqx_map_lib.erl +++ b/apps/emqx/src/emqx_map_lib.erl @@ -197,7 +197,6 @@ covert_keys_to_atom(BinKeyMap, Conv) -> ). %% copy from maps.erl OTP24.0 --compile({inline, [error_with_info/2]}). merge_with(Combiner, Map1, Map2) when is_map(Map1), is_map(Map2), diff --git a/apps/emqx_authn/src/emqx_authn_api.erl b/apps/emqx_authn/src/emqx_authn_api.erl index 51a3ea046..9974d66de 100644 --- a/apps/emqx_authn/src/emqx_authn_api.erl +++ b/apps/emqx_authn/src/emqx_authn_api.erl @@ -89,7 +89,8 @@ delete_user/3, find_user/3, update_user/4, - serialize_error/1 + serialize_error/1, + aggregate_metrics/1 ]). -elvis([{elvis_style, god_modules, disable}]). @@ -992,7 +993,7 @@ aggregate_metrics([]) -> empty_metrics_and_status; aggregate_metrics([HeadMetrics | AllMetrics]) -> CombinerFun = - fun ComFun(Val1, Val2) -> + fun ComFun(_Key, Val1, Val2) -> case erlang:is_map(Val1) of true -> emqx_map_lib:merge_with(ComFun, Val1, Val2); false -> Val1 + Val2 diff --git a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl index 7889143f3..d7342185a 100644 --- a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl @@ -119,6 +119,23 @@ t_listener_authenticator_move(_) -> t_listener_authenticator_import_users(_) -> test_authenticator_import_users(["listeners", ?TCP_DEFAULT]). +t_aggregate_metrics(_) -> + Metrics = #{ 'emqx@node1.emqx.io' => #{metrics => + #{failed => 0,matched => 1,rate => 0.0, + rate_last5m => 0.0,rate_max => 0.1, + success => 1} + }, + 'emqx@node2.emqx.io' => #{metrics => + #{failed => 0,matched => 1,rate => 0.0, + rate_last5m => 0.0,rate_max => 0.1, + success => 1} + } + }, + Res = emqx_authn_api:aggregate_metrics(maps:values(Metrics)), + ?assertEqual(#{metrics => + #{failed => 0,matched => 2,rate => 0.0,rate_last5m => 0.0, + rate_max => 0.2,success => 2}}, Res). + test_authenticators(PathPrefix) -> ValidConfig = emqx_authn_test_lib:http_example(), {ok, 200, _} = request( diff --git a/apps/emqx_authz/src/emqx_authz_api_sources.erl b/apps/emqx_authz/src/emqx_authz_api_sources.erl index c05f9f133..22bfbac42 100644 --- a/apps/emqx_authz/src/emqx_authz_api_sources.erl +++ b/apps/emqx_authz/src/emqx_authz_api_sources.erl @@ -46,7 +46,8 @@ -export([ sources/2, source/2, - move_source/2 + move_source/2, + aggregate_metrics/1 ]). api_spec() -> @@ -373,7 +374,7 @@ aggregate_metrics([]) -> empty_metrics_and_status; aggregate_metrics([HeadMetrics | AllMetrics]) -> CombinerFun = - fun ComFun(Val1, Val2) -> + fun ComFun(_Key, Val1, Val2) -> case erlang:is_map(Val1) of true -> emqx_map_lib:merge_with(ComFun, Val1, Val2); false -> Val1 + Val2 diff --git a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl index 7cf4472bc..a41f98d27 100644 --- a/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_api_sources_SUITE.erl @@ -448,6 +448,23 @@ t_move_source(_) -> ok. +t_aggregate_metrics(_) -> + Metrics = #{ 'emqx@node1.emqx.io' => #{metrics => + #{failed => 0,matched => 1,rate => 0.0, + rate_last5m => 0.0,rate_max => 0.1, + success => 1} + }, + 'emqx@node2.emqx.io' => #{metrics => + #{failed => 0,matched => 1,rate => 0.0, + rate_last5m => 0.0,rate_max => 0.1, + success => 1} + } + }, + Res = emqx_authn_api:aggregate_metrics(maps:values(Metrics)), + ?assertEqual(#{metrics => + #{failed => 0,matched => 2,rate => 0.0,rate_last5m => 0.0, + rate_max => 0.2,success => 2}}, Res). + get_sources(Result) -> maps:get(<<"sources">>, jsx:decode(Result), []).