From a5a8aa3b6de810ccdb2cc646972ab5bfdff3f152 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 4 Jan 2022 22:48:39 -0800 Subject: [PATCH 01/18] feat(rule_metrics): add more metrics to the rule engine --- .../src/emqx_rule_metrics.erl | 97 +++++++++++++++---- .../src/emqx_rule_runtime.erl | 24 +++-- .../test/emqx_rule_metrics_SUITE.erl | 7 ++ 3 files changed, 101 insertions(+), 27 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index bc2b04c07..53bfd9bb5 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -25,16 +25,20 @@ , stop/0 ]). --export([ get_rules_matched/1 - , get_actions_taken/1 +-export([ get_actions_taken/1 , get_actions_success/1 , get_actions_error/1 , get_actions_exception/1 , get_actions_retry/1 + , get_rules_matched/1 + , get_rules_failed/1 + , get_rules_passed/1 + , get_rules_exception/1 + , get_rules_no_result/1 + ]). --export([ inc_rules_matched/1 - , inc_rules_matched/2 +-export([ inc_rules_matched/2 , inc_actions_taken/1 , inc_actions_taken/2 , inc_actions_success/1 @@ -45,6 +49,11 @@ , inc_actions_exception/2 , inc_actions_retry/1 , inc_actions_retry/2 + , inc_rules_matched/1 + , inc_rules_failed/1 + , inc_rules_passed/1 + , inc_rules_exception/1 + , inc_rules_no_result/1 ]). -export([ inc/2 @@ -145,6 +154,10 @@ get_overall_rule_speed() -> get_rule_metrics(Id) -> #{max := Max, current := Current, last5m := Last5M} = get_rule_speed(Id), #{matched => get_rules_matched(Id), + failed => get_rules_failed(Id), + passed => get_rules_passed(Id), + exception => get_rules_exception(Id), + no_result => get_rules_no_result(Id), speed => Current, speed_max => Max, speed_last5m => Last5M @@ -181,11 +194,6 @@ inc(Id, Metric, Val) -> inc_overall(Metric, Val) -> emqx_metrics:inc(Metric, Val). -inc_rules_matched(Id) -> - inc_rules_matched(Id, 1). -inc_rules_matched(Id, Val) -> - inc(Id, 'rules.matched', Val). - inc_actions_taken(Id) -> inc_actions_taken(Id, 1). inc_actions_taken(Id, Val) -> @@ -211,8 +219,32 @@ inc_actions_retry(Id) -> inc_actions_retry(Id, Val) -> inc(Id, 'actions.retry', Val). -get_rules_matched(Id) -> - get(Id, 'rules.matched'). +inc_rules_matched(Id) -> + inc_rules_matched(Id, 1). +inc_rules_matched(Id, Val) -> + inc(Id, 'rules.matched', Val). + +inc_rules_failed(Id) -> + inc_rules_failed(Id, 1). +inc_rules_failed(Id, Val) -> + inc(Id, 'rules.failed', Val). + +inc_rules_passed(Id) -> + inc_rules_passed(Id, 1). +inc_rules_passed(Id, Val) -> + inc(Id, 'rules.passed', Val). + +inc_rules_exception(Id) -> + inc_rules_exception(Id, 1). +inc_rules_exception(Id, Val) -> + inc(Id, 'rules.failed', Val), + inc(Id, 'rules.exception', Val). + +inc_rules_no_result(Id) -> + inc_rules_no_result(Id, 1). +inc_rules_no_result(Id, Val) -> + inc(Id, 'rules.failed', Val), + inc(Id, 'rules.no_result', Val). get_actions_taken(Id) -> get(Id, 'actions.taken'). @@ -229,6 +261,21 @@ get_actions_exception(Id) -> get_actions_retry(Id) -> get(Id, 'actions.retry'). +get_rules_matched(Id) -> + get(Id, 'rules.matched'). + +get_rules_failed(Id) -> + get(Id, 'rules.failed'). + +get_rules_passed(Id) -> + get(Id, 'rules.passed'). + +get_rules_exception(Id) -> + get(Id, 'rules.exception'). + +get_rules_no_result(Id) -> + get(Id, 'rules.no_result'). + start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). @@ -420,21 +467,29 @@ precision(Float, N) -> %% Metrics Definitions %%------------------------------------------------------------------------------ -max_counters_size() -> 7. +max_counters_size() -> 11. -metrics_idx('rules.matched') -> 1; -metrics_idx('actions.success') -> 2; -metrics_idx('actions.error') -> 3; -metrics_idx('actions.taken') -> 4; -metrics_idx('actions.exception') -> 5; -metrics_idx('actions.retry') -> 6; -metrics_idx(_) -> 7. +metrics_idx('actions.success') -> 1; +metrics_idx('actions.error') -> 2; +metrics_idx('actions.taken') -> 3; +metrics_idx('actions.exception') -> 4; +metrics_idx('actions.retry') -> 5; +metrics_idx('rules.matched') -> 6; +metrics_idx('rules.failed') -> 7; +metrics_idx('rules.passed') -> 8; +metrics_idx('rules.exception') -> 9; +metrics_idx('rules.no_result') -> 10; +metrics_idx(_) -> 11. overall_metrics() -> - [ 'rules.matched' - , 'actions.success' + [ 'actions.success' , 'actions.error' , 'actions.taken' , 'actions.exception' , 'actions.retry' + , 'rules.matched' + , 'rules.failed' + , 'rules.passed' + , 'rules.exception' + , 'rules.no_result' ]. diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index f9e210ab3..25addb817 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -51,6 +51,7 @@ apply_rules([], _Input) -> apply_rules([#rule{enabled = false}|More], Input) -> apply_rules(More, Input); apply_rules([Rule = #rule{id = RuleID}|More], Input) -> + ok = emqx_rule_metrics:inc_rules_matched(RuleID), try apply_rule_discard_result(Rule, Input) catch %% ignore the errors if select or match failed @@ -89,15 +90,21 @@ do_apply_rule(#rule{id = RuleId, on_action_failed = OnFailed, actions = Actions}, Input) -> {Selected, Collection} = ?RAISE(select_and_collect(Fields, Input), + emqx_rule_metrics:inc_rules_exception(RuleId), {select_and_collect_error, {_EXCLASS_,_EXCPTION_,_ST_}}), ColumnsAndSelected = maps:merge(Input, Selected), case ?RAISE(match_conditions(Conditions, ColumnsAndSelected), + emqx_rule_metrics:inc_rules_exception(RuleId), {match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true -> - ok = emqx_rule_metrics:inc(RuleId, 'rules.matched'), - Collection2 = filter_collection(Input, InCase, DoEach, Collection), + Collection2 = filter_collection(RuleId, Input, InCase, DoEach, Collection), + case Collection2 of + [] -> emqx_rule_metrics:inc_rules_no_result(RuleId); + _ -> emqx_rule_metrics:inc_rules_passed(RuleId) + end, {ok, [take_actions(Actions, Coll, Input, OnFailed) || Coll <- Collection2]}; false -> + ok = emqx_rule_metrics:inc_rules_no_result(RuleId), {error, nomatch} end; @@ -107,14 +114,17 @@ do_apply_rule(#rule{id = RuleId, conditions = Conditions, on_action_failed = OnFailed, actions = Actions}, Input) -> - Selected = ?RAISE(select_and_transform(Fields, Input), + Selected = ?RAISE(select_and_transform(Fields, Input), + emqx_rule_metrics:inc_rules_exception(RuleId), {select_and_transform_error, {_EXCLASS_,_EXCPTION_,_ST_}}), case ?RAISE(match_conditions(Conditions, maps:merge(Input, Selected)), + emqx_rule_metrics:inc_rules_exception(RuleId), {match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true -> - ok = emqx_rule_metrics:inc(RuleId, 'rules.matched'), + ok = emqx_rule_metrics:inc_rules_passed(RuleId), {ok, take_actions(Actions, Selected, Input, OnFailed)}; false -> + ok = emqx_rule_metrics:inc_rules_no_result(RuleId), {error, nomatch} end. @@ -166,16 +176,18 @@ select_and_collect([Field|More], Input, {Output, LastKV}) -> {nested_put(Key, Val, Output), LastKV}). %% Filter each item got from FOREACH --dialyzer({nowarn_function, filter_collection/4}). -filter_collection(Input, InCase, DoEach, {CollKey, CollVal}) -> +-dialyzer({nowarn_function, filter_collection/5}). +filter_collection(RuleId, Input, InCase, DoEach, {CollKey, CollVal}) -> lists:filtermap( fun(Item) -> InputAndItem = maps:merge(Input, #{CollKey => Item}), case ?RAISE(match_conditions(InCase, InputAndItem), + emqx_rule_metrics:inc_rules_exception(RuleId), {match_incase_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true when DoEach == [] -> {true, InputAndItem}; true -> {true, ?RAISE(select_and_transform(DoEach, InputAndItem), + emqx_rule_metrics:inc_rules_exception(RuleId), {doeach_error, {_EXCLASS_,_EXCPTION_,_ST_}})}; false -> false end diff --git a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl index e7c543c91..81c95bf23 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl @@ -92,9 +92,16 @@ t_rule(_) -> ok = emqx_rule_metrics:create_rule_metrics(<<"rule:1">>), ok = emqx_rule_metrics:create_rule_metrics(<<"rule2">>), ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.matched'), + ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.passed'), + ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.exception'), + ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.no_result'), ok = emqx_rule_metrics:inc(<<"rule2">>, 'rules.matched'), ok = emqx_rule_metrics:inc(<<"rule2">>, 'rules.matched'), ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.matched')), + ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.passed')), + ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.exception')), + ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.no_result')), + ?assertEqual(2, emqx_rule_metrics:get(<<"rule:1">>, 'rules.failed')), ?assertEqual(2, emqx_rule_metrics:get(<<"rule2">>, 'rules.matched')), ?assertEqual(0, emqx_rule_metrics:get(<<"rule3">>, 'rules.matched')), ?assertEqual(3, emqx_rule_metrics:get_overall('rules.matched')), From 88913a9144100e6e7fa76de4430967d840460559 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 01:20:53 -0800 Subject: [PATCH 02/18] test(rule_engine_metrics): add test 't_metrics' --- .../test/emqx_rule_engine_SUITE.erl | 41 +++++++++++++++++++ .../test/emqx_rule_metrics_SUITE.erl | 3 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index d424c9f8a..0637d06f9 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -38,6 +38,7 @@ all() -> , {group, events} , {group, multi_actions} , {group, bugs} + , {group, rule_metrics} ]. suite() -> @@ -125,6 +126,9 @@ groups() -> t_sqlparse_true_false, t_sqlparse_new_map ]}, + {rule_metrics, [], + [t_metrics + ]}, {events, [], [t_events ]}, @@ -1327,6 +1331,43 @@ t_sqlselect_3(_Config) -> emqtt:stop(Client), emqx_rule_registry:remove_rule(TopicRule). +t_metrics(_Config) -> + ok = emqx_rule_engine:load_providers(), + TopicRule = create_simple_repub_rule( + <<"t2">>, + "SELECT payload.msg as msg " + "FROM \"t1\" " + "WHERE msg= 'hello' "), + #rule{id = RuleId} = TopicRule, + ?assertEqual(0, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), + + {ok, Client} = emqtt:start_link([{username, <<"emqx">>}]), + {ok, _} = emqtt:connect(Client), + ct:sleep(200), + + emqtt:publish(Client, <<"t1">>, <<"{\"msg\":\"hello\"}">>, 0), + ct:sleep(200), + ?assertEqual(1, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), + + emqtt:publish(Client, <<"t1">>, <<"{\"msg1\":\"hello\"}">>, 0), + ct:sleep(200), + ?assertEqual(2, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_no_result(RuleId)), + + emqtt:stop(Client), + emqx_rule_registry:remove_rule(TopicRule). + t_sqlselect_multi_actoins_1(Config) -> %% We create 2 actions in the same rule: %% The first will fail and we need to make sure the diff --git a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl index 81c95bf23..342dcddac 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl @@ -95,13 +95,14 @@ t_rule(_) -> ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.passed'), ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.exception'), ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.no_result'), + ok = emqx_rule_metrics:inc(<<"rule:1">>, 'rules.failed'), ok = emqx_rule_metrics:inc(<<"rule2">>, 'rules.matched'), ok = emqx_rule_metrics:inc(<<"rule2">>, 'rules.matched'), ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.matched')), ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.passed')), ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.exception')), ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.no_result')), - ?assertEqual(2, emqx_rule_metrics:get(<<"rule:1">>, 'rules.failed')), + ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.failed')), ?assertEqual(2, emqx_rule_metrics:get(<<"rule2">>, 'rules.matched')), ?assertEqual(0, emqx_rule_metrics:get(<<"rule3">>, 'rules.matched')), ?assertEqual(3, emqx_rule_metrics:get_overall('rules.matched')), From c2870b3322a2e98d0650527026e420eeb3e301d0 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 01:57:18 -0800 Subject: [PATCH 03/18] test(rule_engint_metrics): add test for 'FOREACH' --- .../test/emqx_rule_engine_SUITE.erl | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index 0637d06f9..34d19f083 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -127,7 +127,8 @@ groups() -> t_sqlparse_new_map ]}, {rule_metrics, [], - [t_metrics + [t_metrics, + t_metrics1 ]}, {events, [], [t_events @@ -1368,6 +1369,53 @@ t_metrics(_Config) -> emqtt:stop(Client), emqx_rule_registry:remove_rule(TopicRule). +message() -> + <<"{\"date\": \"2020-04-24\", + \"sensors\": [ + {\"name\": \"a\", \"idx \":0}, + {\"name\": \"b\", \"idx \":1}, + {\"name\": \"c\", \"idx \":2} + ]}">>. + +t_metrics1(_Config) -> + ok = emqx_rule_engine:load_providers(), + TopicRule = create_simple_repub_rule( + <<"t2">>, + "FOREACH payload.sensors " + "DO clientid,item.name as name, item.idx as idx " + "INCASE item.idx >= 1 " + "FROM \"t1\" "), + #rule{id = RuleId} = TopicRule, + ?assertEqual(0, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), + + {ok, Client} = emqtt:start_link([{username, <<"emqx">>}]), + {ok, _} = emqtt:connect(Client), + ct:sleep(200), + + + emqtt:publish(Client, <<"t1">>, message(), 0), + ct:sleep(200), + ?assertEqual(1, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), + + emqtt:publish(Client, <<"t1">>, <<"{\"msg1\":\"hello\"}">>, 0), + ct:sleep(200), + ?assertEqual(2, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(1, emqx_rule_metrics:get_rules_no_result(RuleId)), + + emqtt:stop(Client), + emqx_rule_registry:remove_rule(TopicRule). + t_sqlselect_multi_actoins_1(Config) -> %% We create 2 actions in the same rule: %% The first will fail and we need to make sure the From e5993c9f72e47629ad2aa966403bdd8cedaf1fbe Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 02:08:40 -0800 Subject: [PATCH 04/18] refactor(rule_engine_metrics): remove function 'message()' --- .../test/emqx_rule_engine_SUITE.erl | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index 34d19f083..6e0a0859f 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -1369,14 +1369,6 @@ t_metrics(_Config) -> emqtt:stop(Client), emqx_rule_registry:remove_rule(TopicRule). -message() -> - <<"{\"date\": \"2020-04-24\", - \"sensors\": [ - {\"name\": \"a\", \"idx \":0}, - {\"name\": \"b\", \"idx \":1}, - {\"name\": \"c\", \"idx \":2} - ]}">>. - t_metrics1(_Config) -> ok = emqx_rule_engine:load_providers(), TopicRule = create_simple_repub_rule( @@ -1396,8 +1388,13 @@ t_metrics1(_Config) -> {ok, _} = emqtt:connect(Client), ct:sleep(200), - - emqtt:publish(Client, <<"t1">>, message(), 0), + Message = <<"{\"date\": \"2020-04-24\", + \"sensors\": [ + {\"name\": \"a\", \"idx \":0}, + {\"name\": \"b\", \"idx \":1}, + {\"name\": \"c\", \"idx \":2} + ]}">>, + emqtt:publish(Client, <<"t1">>, Message, 0), ct:sleep(200), ?assertEqual(1, emqx_rule_metrics:get_rules_matched(RuleId)), ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), From c214af2ac0e73dcf34db3241f54df446b6d47403 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 18:51:28 -0800 Subject: [PATCH 05/18] fix(rule_engine_metics): centralized statistics exception --- .../src/emqx_rule_runtime.erl | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index 25addb817..857a817f3 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -51,23 +51,27 @@ apply_rules([], _Input) -> apply_rules([#rule{enabled = false}|More], Input) -> apply_rules(More, Input); apply_rules([Rule = #rule{id = RuleID}|More], Input) -> - ok = emqx_rule_metrics:inc_rules_matched(RuleID), try apply_rule_discard_result(Rule, Input) catch %% ignore the errors if select or match failed _:{select_and_transform_error, Error} -> + emqx_rule_metrics:inc_rules_exception(RuleId), ?LOG(warning, "SELECT clause exception for ~s failed: ~p", [RuleID, Error]); _:{match_conditions_error, Error} -> + emqx_rule_metrics:inc_rules_exception(RuleId), ?LOG(warning, "WHERE clause exception for ~s failed: ~p", [RuleID, Error]); _:{select_and_collect_error, Error} -> + emqx_rule_metrics:inc_rules_exception(RuleId), ?LOG(warning, "FOREACH clause exception for ~s failed: ~p", [RuleID, Error]); _:{match_incase_error, Error} -> + emqx_rule_metrics:inc_rules_exception(RuleId), ?LOG(warning, "INCASE clause exception for ~s failed: ~p", [RuleID, Error]); _:Error:StkTrace -> + emqx_rule_metrics:inc_rules_exception(RuleId), ?LOG(error, "Apply rule ~s failed: ~p. Stacktrace:~n~p", [RuleID, Error, StkTrace]) end, @@ -79,6 +83,7 @@ apply_rule_discard_result(Rule, Input) -> apply_rule(Rule = #rule{id = RuleID}, Input) -> clear_rule_payload(), + ok = emqx_rule_metrics:inc_rules_matched(RuleID), do_apply_rule(Rule, add_metadata(Input, #{rule_id => RuleID})). do_apply_rule(#rule{id = RuleId, @@ -89,15 +94,13 @@ do_apply_rule(#rule{id = RuleId, conditions = Conditions, on_action_failed = OnFailed, actions = Actions}, Input) -> - {Selected, Collection} = ?RAISE(select_and_collect(Fields, Input), - emqx_rule_metrics:inc_rules_exception(RuleId), + {Selected, Collection} = ?RAISE(select_and_collect(Fields, Input), {select_and_collect_error, {_EXCLASS_,_EXCPTION_,_ST_}}), ColumnsAndSelected = maps:merge(Input, Selected), case ?RAISE(match_conditions(Conditions, ColumnsAndSelected), - emqx_rule_metrics:inc_rules_exception(RuleId), {match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true -> - Collection2 = filter_collection(RuleId, Input, InCase, DoEach, Collection), + Collection2 = filter_collection(Input, InCase, DoEach, Collection), case Collection2 of [] -> emqx_rule_metrics:inc_rules_no_result(RuleId); _ -> emqx_rule_metrics:inc_rules_passed(RuleId) @@ -115,10 +118,8 @@ do_apply_rule(#rule{id = RuleId, on_action_failed = OnFailed, actions = Actions}, Input) -> Selected = ?RAISE(select_and_transform(Fields, Input), - emqx_rule_metrics:inc_rules_exception(RuleId), {select_and_transform_error, {_EXCLASS_,_EXCPTION_,_ST_}}), case ?RAISE(match_conditions(Conditions, maps:merge(Input, Selected)), - emqx_rule_metrics:inc_rules_exception(RuleId), {match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true -> ok = emqx_rule_metrics:inc_rules_passed(RuleId), @@ -176,18 +177,16 @@ select_and_collect([Field|More], Input, {Output, LastKV}) -> {nested_put(Key, Val, Output), LastKV}). %% Filter each item got from FOREACH --dialyzer({nowarn_function, filter_collection/5}). -filter_collection(RuleId, Input, InCase, DoEach, {CollKey, CollVal}) -> +-dialyzer({nowarn_function, filter_collection/4}). +filter_collection(Input, InCase, DoEach, {CollKey, CollVal}) -> lists:filtermap( fun(Item) -> InputAndItem = maps:merge(Input, #{CollKey => Item}), case ?RAISE(match_conditions(InCase, InputAndItem), - emqx_rule_metrics:inc_rules_exception(RuleId), {match_incase_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of true when DoEach == [] -> {true, InputAndItem}; true -> {true, ?RAISE(select_and_transform(DoEach, InputAndItem), - emqx_rule_metrics:inc_rules_exception(RuleId), {doeach_error, {_EXCLASS_,_EXCPTION_,_ST_}})}; false -> false end From 2608798826aad1b769dd0edb865435d73fb9a849 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 18:56:34 -0800 Subject: [PATCH 06/18] fix(rule_engine_metrics): fix RuleID reference --- apps/emqx_rule_engine/src/emqx_rule_runtime.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index 857a817f3..2b093bcc4 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -55,23 +55,23 @@ apply_rules([Rule = #rule{id = RuleID}|More], Input) -> catch %% ignore the errors if select or match failed _:{select_and_transform_error, Error} -> - emqx_rule_metrics:inc_rules_exception(RuleId), + emqx_rule_metrics:inc_rules_exception(RuleID), ?LOG(warning, "SELECT clause exception for ~s failed: ~p", [RuleID, Error]); _:{match_conditions_error, Error} -> - emqx_rule_metrics:inc_rules_exception(RuleId), + emqx_rule_metrics:inc_rules_exception(RuleID), ?LOG(warning, "WHERE clause exception for ~s failed: ~p", [RuleID, Error]); _:{select_and_collect_error, Error} -> - emqx_rule_metrics:inc_rules_exception(RuleId), + emqx_rule_metrics:inc_rules_exception(RuleID), ?LOG(warning, "FOREACH clause exception for ~s failed: ~p", [RuleID, Error]); _:{match_incase_error, Error} -> - emqx_rule_metrics:inc_rules_exception(RuleId), + emqx_rule_metrics:inc_rules_exception(RuleID), ?LOG(warning, "INCASE clause exception for ~s failed: ~p", [RuleID, Error]); _:Error:StkTrace -> - emqx_rule_metrics:inc_rules_exception(RuleId), + emqx_rule_metrics:inc_rules_exception(RuleID), ?LOG(error, "Apply rule ~s failed: ~p. Stacktrace:~n~p", [RuleID, Error, StkTrace]) end, From d7a3ade2007fda4dde1fc87839eb5ca447a8747a Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 19:00:59 -0800 Subject: [PATCH 07/18] fix(rule_engine_matrics): remove more space --- apps/emqx_rule_engine/src/emqx_rule_runtime.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl index 2b093bcc4..6c24c899e 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_runtime.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_runtime.erl @@ -94,7 +94,7 @@ do_apply_rule(#rule{id = RuleId, conditions = Conditions, on_action_failed = OnFailed, actions = Actions}, Input) -> - {Selected, Collection} = ?RAISE(select_and_collect(Fields, Input), + {Selected, Collection} = ?RAISE(select_and_collect(Fields, Input), {select_and_collect_error, {_EXCLASS_,_EXCPTION_,_ST_}}), ColumnsAndSelected = maps:merge(Input, Selected), case ?RAISE(match_conditions(Conditions, ColumnsAndSelected), @@ -117,7 +117,7 @@ do_apply_rule(#rule{id = RuleId, conditions = Conditions, on_action_failed = OnFailed, actions = Actions}, Input) -> - Selected = ?RAISE(select_and_transform(Fields, Input), + Selected = ?RAISE(select_and_transform(Fields, Input), {select_and_transform_error, {_EXCLASS_,_EXCPTION_,_ST_}}), case ?RAISE(match_conditions(Conditions, maps:merge(Input, Selected)), {match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of From fae49ad228f2854339ff684fc8adbb39a6a4ac53 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 19:03:28 -0800 Subject: [PATCH 08/18] fix(rule_engine_metrics): remove more space --- apps/emqx_rule_engine/src/emqx_rule_metrics.erl | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index 53bfd9bb5..0f8e1a7f4 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -35,7 +35,6 @@ , get_rules_passed/1 , get_rules_exception/1 , get_rules_no_result/1 - ]). -export([ inc_rules_matched/2 From 1211c658fcfd4b12cfd28c7248dda61b30dd28a3 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 19:18:16 -0800 Subject: [PATCH 09/18] fix(emqx_rule_engine): change vsn to 4.3.7 --- apps/emqx_rule_engine/src/emqx_rule_engine.app.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.app.src b/apps/emqx_rule_engine/src/emqx_rule_engine.app.src index 66af0da21..dd39cfc40 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.app.src +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.app.src @@ -1,6 +1,6 @@ {application, emqx_rule_engine, [{description, "EMQ X Rule Engine"}, - {vsn, "4.3.6"}, % strict semver, bump manually! + {vsn, "4.3.7"}, % strict semver, bump manually! {modules, []}, {registered, [emqx_rule_engine_sup, emqx_rule_registry]}, {applications, [kernel,stdlib,rulesql,getopt]}, From 2074dd63f905f56cf52dd7d5bcc15df96c81845b Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Wed, 5 Jan 2022 18:57:52 -0800 Subject: [PATCH 10/18] test(rule_engine_metrics): add more test --- .../test/emqx_rule_engine_SUITE.erl | 91 ++++++++++++------- 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl index 6e0a0859f..f430c3d4e 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -1336,36 +1336,41 @@ t_metrics(_Config) -> ok = emqx_rule_engine:load_providers(), TopicRule = create_simple_repub_rule( <<"t2">>, - "SELECT payload.msg as msg " + "SELECT payload.msg as msg, payload.idx as idx " "FROM \"t1\" " - "WHERE msg= 'hello' "), + "WHERE msg = 'hello' and idx + 1 > 2 "), #rule{id = RuleId} = TopicRule, ?assertEqual(0, emqx_rule_metrics:get_rules_matched(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_passed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), - {ok, Client} = emqtt:start_link([{username, <<"emqx">>}]), {ok, _} = emqtt:connect(Client), ct:sleep(200), - - emqtt:publish(Client, <<"t1">>, <<"{\"msg\":\"hello\"}">>, 0), - ct:sleep(200), - ?assertEqual(1, emqx_rule_metrics:get_rules_matched(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + PublishMoreTimes = fun(SomeMessage, Times) -> + [begin + emqtt:publish(Client, <<"t1">>, SomeMessage, 0), + ct:sleep(200) + end || _ <- lists:seq(1, Times)] end, + PublishMoreTimes(<<"{\"msg\":\"hello\", \"idx\":5}">>, 10), + ?assertEqual(10, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), - - emqtt:publish(Client, <<"t1">>, <<"{\"msg1\":\"hello\"}">>, 0), - ct:sleep(200), - ?assertEqual(2, emqx_rule_metrics:get_rules_matched(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_failed(RuleId)), + PublishMoreTimes(<<"{\"msg\":\"hello\", \"idx\":0}">>, 10), + ?assertEqual(20, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_no_result(RuleId)), - + ?assertEqual(10, emqx_rule_metrics:get_rules_no_result(RuleId)), + PublishMoreTimes(<<"{\"msg\":\"hello\", \"idx\":\"somevalue\"}">>, 10), + ?assertEqual(30, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(20, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_no_result(RuleId)), emqtt:stop(Client), emqx_rule_registry:remove_rule(TopicRule). @@ -1374,7 +1379,7 @@ t_metrics1(_Config) -> TopicRule = create_simple_repub_rule( <<"t2">>, "FOREACH payload.sensors " - "DO clientid,item.name as name, item.idx as idx " + "DO clientid,item.name as name, item.idx + 1 as idx " "INCASE item.idx >= 1 " "FROM \"t1\" "), #rule{id = RuleId} = TopicRule, @@ -1382,33 +1387,51 @@ t_metrics1(_Config) -> ?assertEqual(0, emqx_rule_metrics:get_rules_passed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), - ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), - + ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), {ok, Client} = emqtt:start_link([{username, <<"emqx">>}]), {ok, _} = emqtt:connect(Client), ct:sleep(200), - + PublishMoreTimes = fun(SomeMessage, Times) -> + [begin + emqtt:publish(Client, <<"t1">>, SomeMessage, 0), + ct:sleep(200) + end || _ <- lists:seq(1, Times)] end, Message = <<"{\"date\": \"2020-04-24\", \"sensors\": [ - {\"name\": \"a\", \"idx \":0}, - {\"name\": \"b\", \"idx \":1}, - {\"name\": \"c\", \"idx \":2} + {\"name\": \"a\", \"idx\":0}, + {\"name\": \"b\", \"idx\":1}, + {\"name\": \"c\", \"idx\":2} ]}">>, - emqtt:publish(Client, <<"t1">>, Message, 0), - ct:sleep(200), - ?assertEqual(1, emqx_rule_metrics:get_rules_matched(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), + PublishMoreTimes(Message, 10), + ?assertEqual(10, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_no_result(RuleId)), - - emqtt:publish(Client, <<"t1">>, <<"{\"msg1\":\"hello\"}">>, 0), - ct:sleep(200), - ?assertEqual(2, emqx_rule_metrics:get_rules_matched(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_passed(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_failed(RuleId)), + Message1 = <<"{\"date\": \"2020-04-24\", + \"sensors\": [ + {\"name\": \"a\", \"idx\":0}, + {\"name\": \"b\", \"idx\":0}, + {\"name\": \"c\", \"idx\":0} + ]}">>, + PublishMoreTimes(Message1, 10), + ?assertEqual(20, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_failed(RuleId)), ?assertEqual(0, emqx_rule_metrics:get_rules_exception(RuleId)), - ?assertEqual(1, emqx_rule_metrics:get_rules_no_result(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_no_result(RuleId)), + Message2 = <<"{\"date\": \"2020-04-24\", + \"sensors\": [ + {\"name\": \"a\", \"idx\":0}, + {\"name\": \"b\", \"idx\":1}, + {\"name\": \"c\", \"idx\":\"some string\"} + ]}">>, + PublishMoreTimes(Message2, 10), + ?assertEqual(30, emqx_rule_metrics:get_rules_matched(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_passed(RuleId)), + ?assertEqual(20, emqx_rule_metrics:get_rules_failed(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_exception(RuleId)), + ?assertEqual(10, emqx_rule_metrics:get_rules_no_result(RuleId)), emqtt:stop(Client), emqx_rule_registry:remove_rule(TopicRule). From be81c65edab35e506f53abc23c29ffd1d4b888d6 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Thu, 6 Jan 2022 00:47:17 -0800 Subject: [PATCH 11/18] feat(rule_engine_metics): add hot upgrade feat --- .../src/emqx_rule_metrics.erl | 80 +++++++++++-------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index 0f8e1a7f4..90a3a5d86 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -349,43 +349,55 @@ handle_info(_Info, State) -> {noreply, State}. code_change({down, Vsn}, State = #state{metric_ids = MIDs}, _Extra) - when Vsn =:= "4.2.0"; - Vsn =:= "4.2.1" -> - emqx_metrics:ensure('actions.failure'), - emqx_metrics:set('actions.failure', - emqx_metrics:val('actions.error') - + emqx_metrics:val('actions.exception')), + when Vsn =:= "4.3.0"; + Vsn =:= "4.3.1"; + Vsn =:= "4.3.2"; + Vsn =:= "4.3.3"; + Vsn =:= "4.3.4"; + Vsn =:= "4.3.5"; + Vsn =:= "4.3.6" -> [begin - Matched = get_rules_matched(Id), - Succ = get_actions_success(Id), + Passed = get_rules_passed(Id), + Take = get_actions_taken(Id), + Success = get_actions_success(Id), Error = get_actions_error(Id), - Except = get_actions_exception(Id), + Exception = get_actions_exception(Id), + Retry = get_actions_retry(Id), ok = delete_counters(Id), - ok = create_counters(Id), - inc_rules_matched(Id, Matched), - inc_actions_success(Id, Succ), - inc_actions_error(Id, Error + Except) + ok = create_counters(Id, 7), + inc_rules_matched(Id, Passed), + inc_actions_taken(Id, Take), + inc_actions_success(Id, Success), + inc_actions_error(Id, Error), + inc_actions_exception(Id, Exception), + inc_actions_retry(Id, Retry) end || Id <- sets:to_list(MIDs)], {ok, State}; code_change(Vsn, State = #state{metric_ids = MIDs}, _Extra) - when Vsn =:= "4.2.0"; - Vsn =:= "4.2.1" -> - [emqx_metrics:ensure(Name) - || Name <- - ['actions.error', 'actions.taken', - 'actions.exception', 'actions.retry' - ]], - emqx_metrics:set('actions.error', emqx_metrics:val('actions.failure')), + when Vsn =:= "4.3.0"; + Vsn =:= "4.3.1"; + Vsn =:= "4.3.2"; + Vsn =:= "4.3.3"; + Vsn =:= "4.3.4"; + Vsn =:= "4.3.5"; + Vsn =:= "4.3.6" -> [begin Matched = get_rules_matched(Id), - Succ = get_actions_success(Id), + Take = get_actions_taken(Id), + Success = get_actions_success(Id), Error = get_actions_error(Id), + Exception = get_actions_exception(Id), + Retry = get_actions_retry(Id), ok = delete_counters(Id), ok = create_counters(Id), inc_rules_matched(Id, Matched), - inc_actions_success(Id, Succ), - inc_actions_error(Id, Error) + inc_rules_passed(Id, Matched), + inc_actions_taken(Id, Take), + inc_actions_success(Id, Success), + inc_actions_error(Id, Error), + inc_actions_exception(Id, Exception), + inc_actions_retry(Id, Retry) end || Id <- sets:to_list(MIDs)], {ok, State}; @@ -407,10 +419,12 @@ async_refresh_resource_status() -> spawn(emqx_rule_engine, refresh_resource_status, []). create_counters(Id) -> + create_counters(Id, max_counters_size()). +create_counters(Id, Size) -> case couters_ref(Id) of not_found -> ok = persistent_term:put(?CRefID(Id), - counters:new(max_counters_size(), [write_concurrency])); + counters:new(Size, [write_concurrency])); _Ref -> ok end. @@ -468,12 +482,12 @@ precision(Float, N) -> max_counters_size() -> 11. -metrics_idx('actions.success') -> 1; -metrics_idx('actions.error') -> 2; -metrics_idx('actions.taken') -> 3; -metrics_idx('actions.exception') -> 4; -metrics_idx('actions.retry') -> 5; -metrics_idx('rules.matched') -> 6; +metrics_idx('rules.matched') -> 1; +metrics_idx('actions.success') -> 2; +metrics_idx('actions.error') -> 3; +metrics_idx('actions.taken') -> 4; +metrics_idx('actions.exception') -> 5; +metrics_idx('actions.retry') -> 6; metrics_idx('rules.failed') -> 7; metrics_idx('rules.passed') -> 8; metrics_idx('rules.exception') -> 9; @@ -481,12 +495,12 @@ metrics_idx('rules.no_result') -> 10; metrics_idx(_) -> 11. overall_metrics() -> - [ 'actions.success' + [ 'rules.matched' + , 'actions.success' , 'actions.error' , 'actions.taken' , 'actions.exception' , 'actions.retry' - , 'rules.matched' , 'rules.failed' , 'rules.passed' , 'rules.exception' From 3956eaddd749679f896f05ee6ed0beb42df18619 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Sun, 9 Jan 2022 19:15:14 -0800 Subject: [PATCH 12/18] fix(rule_engine_metrics): add more rulge_engine version to emqx_rule_engine.appup.src --- .../src/emqx_rule_engine.appup.src | 50 ++++++++++++++----- .../src/emqx_rule_metrics.erl | 4 +- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src index c94dc994d..3aeb2cd69 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.appup.src @@ -1,52 +1,78 @@ %% -*- mode: erlang -*- {VSN, - [{"4.3.5",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + [{"4.3.7",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.3.0", - [{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.0"]}}, + {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.1", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.1"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.2", - [{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.2"]}}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.3", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.3"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.3.4", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.4"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + {"4.3.5", + [{update, emqx_rule_metrics, {advanced, ["4.3.5"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + {"4.3.6", + [{update, emqx_rule_metrics, {advanced, ["4.3.6"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], - [{"4.3.5",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + [{"4.3.7",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.3.0", - [{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.0"]}}, + {load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.1", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.1"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.2", - [{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.2"]}}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}, {apply,{emqx_stats,cancel_update,[rule_registery_stats]}}, {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]}, {"4.3.3", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.3"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {"4.3.4", - [{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + [{update, emqx_rule_metrics, {advanced, ["4.3.4"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + {"4.3.5", + [{update, emqx_rule_metrics, {advanced, ["4.3.5"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, + {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, + {"4.3.6", + [{update, emqx_rule_metrics, {advanced, ["4.3.6"]}}, + {load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}, {load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}]}. diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index 90a3a5d86..a77c56745 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -348,7 +348,7 @@ handle_info(ticking, State = #state{rule_speeds = RuleSpeeds0, handle_info(_Info, State) -> {noreply, State}. -code_change({down, Vsn}, State = #state{metric_ids = MIDs}, _Extra) +code_change({down, _Vsn}, State = #state{metric_ids = MIDs}, [Vsn]) when Vsn =:= "4.3.0"; Vsn =:= "4.3.1"; Vsn =:= "4.3.2"; @@ -374,7 +374,7 @@ code_change({down, Vsn}, State = #state{metric_ids = MIDs}, _Extra) end || Id <- sets:to_list(MIDs)], {ok, State}; -code_change(Vsn, State = #state{metric_ids = MIDs}, _Extra) +code_change(_Vsn, State = #state{metric_ids = MIDs}, [Vsn]) when Vsn =:= "4.3.0"; Vsn =:= "4.3.1"; Vsn =:= "4.3.2"; From 7605fa5e64bd38dbe881b18c69bdc4a22a15374d Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 11 Jan 2022 01:12:15 -0800 Subject: [PATCH 13/18] fix(rule_engine_metric): remove unused metrics 'overall_metrics' --- .../src/emqx_rule_metrics.erl | 43 ++----------------- .../test/emqx_rule_metrics_SUITE.erl | 25 ----------- 2 files changed, 3 insertions(+), 65 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index a77c56745..bb8313f59 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -58,14 +58,11 @@ -export([ inc/2 , inc/3 , get/2 - , get_overall/1 , get_rule_speed/1 - , get_overall_rule_speed/0 , create_rule_metrics/1 , create_metrics/1 , clear_rule_metrics/1 , clear_metrics/1 - , overall_metrics/0 ]). -export([ get_rule_metrics/1 @@ -137,18 +134,10 @@ get(Id, Metric) -> Ref -> counters:get(Ref, metrics_idx(Metric)) end. --spec(get_overall(atom()) -> number()). -get_overall(Metric) -> - emqx_metrics:val(Metric). - -spec(get_rule_speed(rule_id()) -> map()). get_rule_speed(Id) -> gen_server:call(?MODULE, {get_rule_speed, Id}). --spec(get_overall_rule_speed() -> map()). -get_overall_rule_speed() -> - gen_server:call(?MODULE, get_overall_rule_speed). - -spec(get_rule_metrics(rule_id()) -> map()). get_rule_metrics(Id) -> #{max := Max, current := Current, last5m := Last5M} = get_rule_speed(Id), @@ -186,12 +175,7 @@ inc(Id, Metric, Val) -> counters:add(couters_ref(Id), metrics_idx(Metric), Val); Ref -> counters:add(Ref, metrics_idx(Metric), Val) - end, - inc_overall(Metric, Val). - --spec(inc_overall(atom(), pos_integer()) -> ok). -inc_overall(Metric, Val) -> - emqx_metrics:inc(Metric, Val). + end. inc_actions_taken(Id) -> inc_actions_taken(Id, 1). @@ -280,8 +264,6 @@ start_link() -> init([]) -> erlang:process_flag(trap_exit, true), - %% the overall counters - [ok = emqx_metrics:ensure(Metric)|| Metric <- overall_metrics()], %% the speed metrics erlang:send_after(timer:seconds(?SAMPLING), self(), ticking), {ok, #state{overall_rule_speed = #rule_speed{}}}. @@ -294,9 +276,6 @@ handle_call({get_rule_speed, Id}, _From, State = #state{rule_speeds = RuleSpeeds Speed -> format_rule_speed(Speed) end, State}; -handle_call(get_overall_rule_speed, _From, State = #state{overall_rule_speed = RuleSpeed}) -> - {reply, format_rule_speed(RuleSpeed), State}; - handle_call({create_metrics, Id}, _From, State = #state{metric_ids = MIDs}) -> {reply, create_counters(Id), State#state{metric_ids = sets:add_element(Id, MIDs)}}; @@ -333,17 +312,14 @@ handle_info(ticking, State = #state{rule_speeds = undefined}) -> erlang:send_after(timer:seconds(?SAMPLING), self(), ticking), {noreply, State}; -handle_info(ticking, State = #state{rule_speeds = RuleSpeeds0, - overall_rule_speed = OverallRuleSpeed0}) -> +handle_info(ticking, State = #state{rule_speeds = RuleSpeeds0}) -> RuleSpeeds = maps:map( fun(Id, RuleSpeed) -> calculate_speed(get_rules_matched(Id), RuleSpeed) end, RuleSpeeds0), - OverallRuleSpeed = calculate_speed(get_overall('rules.matched'), OverallRuleSpeed0), async_refresh_resource_status(), erlang:send_after(timer:seconds(?SAMPLING), self(), ticking), - {noreply, State#state{rule_speeds = RuleSpeeds, - overall_rule_speed = OverallRuleSpeed}}; + {noreply, State#state{rule_speeds = RuleSpeeds}}; handle_info(_Info, State) -> {noreply, State}. @@ -493,16 +469,3 @@ metrics_idx('rules.passed') -> 8; metrics_idx('rules.exception') -> 9; metrics_idx('rules.no_result') -> 10; metrics_idx(_) -> 11. - -overall_metrics() -> - [ 'rules.matched' - , 'actions.success' - , 'actions.error' - , 'actions.taken' - , 'actions.exception' - , 'actions.retry' - , 'rules.failed' - , 'rules.passed' - , 'rules.exception' - , 'rules.no_result' - ]. diff --git a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl index 342dcddac..5a8d99d0e 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_metrics_SUITE.erl @@ -55,7 +55,6 @@ end_per_suite(_Config) -> init_per_testcase(_, Config) -> catch emqx_rule_metrics:stop(), {ok, _} = emqx_rule_metrics:start_link(), - [emqx_metrics:set(M, 0) || M <- emqx_rule_metrics:overall_metrics()], Config. end_per_testcase(_, _Config) -> @@ -81,8 +80,6 @@ t_action(_) -> ?assertEqual(1, emqx_rule_metrics:get_actions_exception(<<"action:1">>)), ?assertEqual(2, emqx_rule_metrics:get_actions_taken(<<"action:2">>)), ?assertEqual(0, emqx_rule_metrics:get_actions_taken(<<"action:3">>)), - ?assertEqual(3, emqx_rule_metrics:get_overall('actions.taken')), - ?assertEqual(1, emqx_rule_metrics:get_overall('actions.exception')), ok = emqx_rule_metrics:clear_metrics(<<"action:1">>), ok = emqx_rule_metrics:clear_metrics(<<"action:2">>), ?assertEqual(0, emqx_rule_metrics:get_actions_taken(<<"action:1">>)), @@ -105,7 +102,6 @@ t_rule(_) -> ?assertEqual(1, emqx_rule_metrics:get(<<"rule:1">>, 'rules.failed')), ?assertEqual(2, emqx_rule_metrics:get(<<"rule2">>, 'rules.matched')), ?assertEqual(0, emqx_rule_metrics:get(<<"rule3">>, 'rules.matched')), - ?assertEqual(3, emqx_rule_metrics:get_overall('rules.matched')), ok = emqx_rule_metrics:clear_rule_metrics(<<"rule:1">>), ok = emqx_rule_metrics:clear_rule_metrics(<<"rule2">>). @@ -127,24 +123,11 @@ rule_speed(_) -> ?LET(#{max := Max, current := Current}, emqx_rule_metrics:get_rule_speed(<<"rule1">>), {?assert(Max =< 2), ?assert(Current =< 2)}), - ct:pal("===== Speed: ~p~n", [emqx_rule_metrics:get_overall_rule_speed()]), - ?LET(#{max := Max, current := Current}, emqx_rule_metrics:get_overall_rule_speed(), - {?assert(Max =< 3), - ?assert(Current =< 3)}), ct:sleep(2100), ?LET(#{max := Max, current := Current, last5m := Last5Min}, emqx_rule_metrics:get_rule_speed(<<"rule1">>), {?assert(Max =< 2), ?assert(Current == 0), ?assert(Last5Min =< 0.67)}), - ?LET(#{max := Max, current := Current, last5m := Last5Min}, emqx_rule_metrics:get_overall_rule_speed(), - {?assert(Max =< 3), - ?assert(Current == 0), - ?assert(Last5Min =< 1)}), - ct:sleep(3000), - ?LET(#{max := Max, current := Current, last5m := Last5Min}, emqx_rule_metrics:get_overall_rule_speed(), - {?assert(Max =< 3), - ?assert(Current == 0), - ?assert(Last5Min == 0)}), ok = emqx_rule_metrics:clear_rule_metrics(<<"rule1">>), ok = emqx_rule_metrics:clear_rule_metrics(<<"rule:2">>). @@ -154,14 +137,10 @@ rule_speed(_) -> % t_get(_) -> % error('TODO'). -% t_get_overall(_) -> -% error('TODO'). % t_get_rule_speed(_) -> % error('TODO'). -% t_get_overall_rule_speed(_) -> -% error('TODO'). % t_get_rule_metrics(_) -> % error('TODO'). @@ -171,7 +150,3 @@ rule_speed(_) -> % t_inc(_) -> % error('TODO'). - -% t_overall_metrics(_) -> -% error('TODO'). - From de58c8e7bc4928b64e856ed9cbf2b35e57209497 Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 11 Jan 2022 03:03:18 -0800 Subject: [PATCH 14/18] refactor(rule_engine_metrics): refactor code_change --- .../src/emqx_rule_metrics.erl | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index bb8313f59..7b1fe2f54 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -324,58 +324,60 @@ handle_info(ticking, State = #state{rule_speeds = RuleSpeeds0}) -> handle_info(_Info, State) -> {noreply, State}. -code_change({down, _Vsn}, State = #state{metric_ids = MIDs}, [Vsn]) - when Vsn =:= "4.3.0"; - Vsn =:= "4.3.1"; - Vsn =:= "4.3.2"; - Vsn =:= "4.3.3"; - Vsn =:= "4.3.4"; - Vsn =:= "4.3.5"; - Vsn =:= "4.3.6" -> - [begin - Passed = get_rules_passed(Id), - Take = get_actions_taken(Id), - Success = get_actions_success(Id), - Error = get_actions_error(Id), - Exception = get_actions_exception(Id), - Retry = get_actions_retry(Id), - ok = delete_counters(Id), - ok = create_counters(Id, 7), - inc_rules_matched(Id, Passed), - inc_actions_taken(Id, Take), - inc_actions_success(Id, Success), - inc_actions_error(Id, Error), - inc_actions_exception(Id, Exception), - inc_actions_retry(Id, Retry) - end || Id <- sets:to_list(MIDs)], - {ok, State}; +code_change({down, _Vsn}, State = #state{metric_ids = MIDs}, [Vsn]) -> + case string:tokens(Vsn, ".") of + ["4", "3", Val] -> + case string:to_integer(Val) =< 7 of + true -> + [begin + Passed = get_rules_passed(Id), + Take = get_actions_taken(Id), + Success = get_actions_success(Id), + Error = get_actions_error(Id), + Exception = get_actions_exception(Id), + Retry = get_actions_retry(Id), + ok = delete_counters(Id), + ok = create_counters(Id, 7), + inc_rules_matched(Id, Passed), + inc_actions_taken(Id, Take), + inc_actions_success(Id, Success), + inc_actions_error(Id, Error), + inc_actions_exception(Id, Exception), + inc_actions_retry(Id, Retry) + end || Id <- sets:to_list(MIDs)], + {ok, State}; + false -> {ok, State} + end; + _ -> {ok, State} + end; -code_change(_Vsn, State = #state{metric_ids = MIDs}, [Vsn]) - when Vsn =:= "4.3.0"; - Vsn =:= "4.3.1"; - Vsn =:= "4.3.2"; - Vsn =:= "4.3.3"; - Vsn =:= "4.3.4"; - Vsn =:= "4.3.5"; - Vsn =:= "4.3.6" -> - [begin - Matched = get_rules_matched(Id), - Take = get_actions_taken(Id), - Success = get_actions_success(Id), - Error = get_actions_error(Id), - Exception = get_actions_exception(Id), - Retry = get_actions_retry(Id), - ok = delete_counters(Id), - ok = create_counters(Id), - inc_rules_matched(Id, Matched), - inc_rules_passed(Id, Matched), - inc_actions_taken(Id, Take), - inc_actions_success(Id, Success), - inc_actions_error(Id, Error), - inc_actions_exception(Id, Exception), - inc_actions_retry(Id, Retry) - end || Id <- sets:to_list(MIDs)], - {ok, State}; +code_change(_Vsn, State = #state{metric_ids = MIDs}, [Vsn]) -> + case string:tokens(Vsn, ".") of + ["4", "3", Val] -> + case string:to_integer(Val) =< 7 of + true -> + [begin + Matched = get_rules_matched(Id), + Take = get_actions_taken(Id), + Success = get_actions_success(Id), + Error = get_actions_error(Id), + Exception = get_actions_exception(Id), + Retry = get_actions_retry(Id), + ok = delete_counters(Id), + ok = create_counters(Id), + inc_rules_matched(Id, Matched), + inc_rules_passed(Id, Matched), + inc_actions_taken(Id, Take), + inc_actions_success(Id, Success), + inc_actions_error(Id, Error), + inc_actions_exception(Id, Exception), + inc_actions_retry(Id, Retry) + end || Id <- sets:to_list(MIDs)], + {ok, State}; + false -> {ok, State} + end; + _ -> {ok, State} + end; code_change(_OldVsn, State, _Extra) -> {ok, State}. From da8cd5d10318f9d1e4b713a6ba144f528eca5aed Mon Sep 17 00:00:00 2001 From: EMQ-YangM Date: Tue, 11 Jan 2022 19:22:38 -0800 Subject: [PATCH 15/18] fix(rule_engine_metrics): fxi string:to_integer pattern match error --- apps/emqx_rule_engine/src/emqx_rule_metrics.erl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl index 7b1fe2f54..ed831bc3b 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_metrics.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_metrics.erl @@ -326,8 +326,9 @@ handle_info(_Info, State) -> code_change({down, _Vsn}, State = #state{metric_ids = MIDs}, [Vsn]) -> case string:tokens(Vsn, ".") of - ["4", "3", Val] -> - case string:to_integer(Val) =< 7 of + ["4", "3", SVal] -> + {Val, []} = string:to_integer(SVal), + case Val =< 7 of true -> [begin Passed = get_rules_passed(Id), @@ -353,8 +354,9 @@ code_change({down, _Vsn}, State = #state{metric_ids = MIDs}, [Vsn]) -> code_change(_Vsn, State = #state{metric_ids = MIDs}, [Vsn]) -> case string:tokens(Vsn, ".") of - ["4", "3", Val] -> - case string:to_integer(Val) =< 7 of + ["4", "3", SVal] -> + {Val, []} = string:to_integer(SVal), + case Val =< 7 of true -> [begin Matched = get_rules_matched(Id), From 6de114f82234c634db78d80d52143784537d95eb Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 12 Jan 2022 18:49:01 +0800 Subject: [PATCH 16/18] chore: rename CHANGES.md to CHANGES-4.3.md --- CHANGES.md => CHANGES-4.3.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CHANGES.md => CHANGES-4.3.md (100%) diff --git a/CHANGES.md b/CHANGES-4.3.md similarity index 100% rename from CHANGES.md rename to CHANGES-4.3.md From d7b0e753da286361ebad6e07a48aea8fb6007176 Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Wed, 12 Jan 2022 11:57:02 +0100 Subject: [PATCH 17/18] ci: skip dialyzer race_condition checks backported from 5.0 race_condition check is very RAM demanding --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 25bd95089..fb60981b2 100644 --- a/rebar.config +++ b/rebar.config @@ -17,7 +17,7 @@ deprecated_function_calls,warnings_as_errors,deprecated_functions]}. {dialyzer, [ - {warnings, [unmatched_returns, error_handling, race_conditions]}, + {warnings, [unmatched_returns, error_handling]}, {plt_location, "."}, {plt_prefix, "emqx_dialyzer"}, {plt_apps, all_apps}, From cfc3c076bb46d8e22a79302c62ebe4ce49499694 Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Wed, 12 Jan 2022 21:50:50 +0100 Subject: [PATCH 18/18] build: fix package version regexp match pattern --- build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build b/build index 46cd60bc9..684057bf1 100755 --- a/build +++ b/build @@ -65,7 +65,7 @@ make_relup() { if [ -d "$releases_dir" ]; then while read -r zip; do local base_vsn - base_vsn="$(echo "$zip" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+(-[0-9a-e]{8})?")" + base_vsn="$(echo "$zip" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+(-[0-9a-f]{8})?")" if [ ! -d "$releases_dir/$base_vsn" ]; then local tmp_dir tmp_dir="$(mktemp -d -t emqx.XXXXXXX)"