feat(rule_metrics): add more metrics to the rule engine
This commit is contained in:
parent
a9f37f139d
commit
a5a8aa3b6d
|
@ -25,16 +25,20 @@
|
||||||
, stop/0
|
, stop/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([ get_rules_matched/1
|
-export([ get_actions_taken/1
|
||||||
, get_actions_taken/1
|
|
||||||
, get_actions_success/1
|
, get_actions_success/1
|
||||||
, get_actions_error/1
|
, get_actions_error/1
|
||||||
, get_actions_exception/1
|
, get_actions_exception/1
|
||||||
, get_actions_retry/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
|
-export([ inc_rules_matched/2
|
||||||
, inc_rules_matched/2
|
|
||||||
, inc_actions_taken/1
|
, inc_actions_taken/1
|
||||||
, inc_actions_taken/2
|
, inc_actions_taken/2
|
||||||
, inc_actions_success/1
|
, inc_actions_success/1
|
||||||
|
@ -45,6 +49,11 @@
|
||||||
, inc_actions_exception/2
|
, inc_actions_exception/2
|
||||||
, inc_actions_retry/1
|
, inc_actions_retry/1
|
||||||
, inc_actions_retry/2
|
, 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
|
-export([ inc/2
|
||||||
|
@ -145,6 +154,10 @@ get_overall_rule_speed() ->
|
||||||
get_rule_metrics(Id) ->
|
get_rule_metrics(Id) ->
|
||||||
#{max := Max, current := Current, last5m := Last5M} = get_rule_speed(Id),
|
#{max := Max, current := Current, last5m := Last5M} = get_rule_speed(Id),
|
||||||
#{matched => get_rules_matched(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 => Current,
|
||||||
speed_max => Max,
|
speed_max => Max,
|
||||||
speed_last5m => Last5M
|
speed_last5m => Last5M
|
||||||
|
@ -181,11 +194,6 @@ inc(Id, Metric, Val) ->
|
||||||
inc_overall(Metric, Val) ->
|
inc_overall(Metric, Val) ->
|
||||||
emqx_metrics:inc(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) ->
|
||||||
inc_actions_taken(Id, 1).
|
inc_actions_taken(Id, 1).
|
||||||
inc_actions_taken(Id, Val) ->
|
inc_actions_taken(Id, Val) ->
|
||||||
|
@ -211,8 +219,32 @@ inc_actions_retry(Id) ->
|
||||||
inc_actions_retry(Id, Val) ->
|
inc_actions_retry(Id, Val) ->
|
||||||
inc(Id, 'actions.retry', Val).
|
inc(Id, 'actions.retry', Val).
|
||||||
|
|
||||||
get_rules_matched(Id) ->
|
inc_rules_matched(Id) ->
|
||||||
get(Id, 'rules.matched').
|
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_actions_taken(Id) ->
|
||||||
get(Id, 'actions.taken').
|
get(Id, 'actions.taken').
|
||||||
|
@ -229,6 +261,21 @@ get_actions_exception(Id) ->
|
||||||
get_actions_retry(Id) ->
|
get_actions_retry(Id) ->
|
||||||
get(Id, 'actions.retry').
|
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() ->
|
start_link() ->
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
@ -420,21 +467,29 @@ precision(Float, N) ->
|
||||||
%% Metrics Definitions
|
%% Metrics Definitions
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
max_counters_size() -> 7.
|
max_counters_size() -> 11.
|
||||||
|
|
||||||
metrics_idx('rules.matched') -> 1;
|
metrics_idx('actions.success') -> 1;
|
||||||
metrics_idx('actions.success') -> 2;
|
metrics_idx('actions.error') -> 2;
|
||||||
metrics_idx('actions.error') -> 3;
|
metrics_idx('actions.taken') -> 3;
|
||||||
metrics_idx('actions.taken') -> 4;
|
metrics_idx('actions.exception') -> 4;
|
||||||
metrics_idx('actions.exception') -> 5;
|
metrics_idx('actions.retry') -> 5;
|
||||||
metrics_idx('actions.retry') -> 6;
|
metrics_idx('rules.matched') -> 6;
|
||||||
metrics_idx(_) -> 7.
|
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() ->
|
overall_metrics() ->
|
||||||
[ 'rules.matched'
|
[ 'actions.success'
|
||||||
, 'actions.success'
|
|
||||||
, 'actions.error'
|
, 'actions.error'
|
||||||
, 'actions.taken'
|
, 'actions.taken'
|
||||||
, 'actions.exception'
|
, 'actions.exception'
|
||||||
, 'actions.retry'
|
, 'actions.retry'
|
||||||
|
, 'rules.matched'
|
||||||
|
, 'rules.failed'
|
||||||
|
, 'rules.passed'
|
||||||
|
, 'rules.exception'
|
||||||
|
, 'rules.no_result'
|
||||||
].
|
].
|
||||||
|
|
|
@ -51,6 +51,7 @@ apply_rules([], _Input) ->
|
||||||
apply_rules([#rule{enabled = false}|More], Input) ->
|
apply_rules([#rule{enabled = false}|More], Input) ->
|
||||||
apply_rules(More, Input);
|
apply_rules(More, Input);
|
||||||
apply_rules([Rule = #rule{id = RuleID}|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)
|
try apply_rule_discard_result(Rule, Input)
|
||||||
catch
|
catch
|
||||||
%% ignore the errors if select or match failed
|
%% ignore the errors if select or match failed
|
||||||
|
@ -89,15 +90,21 @@ do_apply_rule(#rule{id = RuleId,
|
||||||
on_action_failed = OnFailed,
|
on_action_failed = OnFailed,
|
||||||
actions = Actions}, Input) ->
|
actions = Actions}, Input) ->
|
||||||
{Selected, Collection} = ?RAISE(select_and_collect(Fields, Input),
|
{Selected, Collection} = ?RAISE(select_and_collect(Fields, Input),
|
||||||
|
emqx_rule_metrics:inc_rules_exception(RuleId),
|
||||||
{select_and_collect_error, {_EXCLASS_,_EXCPTION_,_ST_}}),
|
{select_and_collect_error, {_EXCLASS_,_EXCPTION_,_ST_}}),
|
||||||
ColumnsAndSelected = maps:merge(Input, Selected),
|
ColumnsAndSelected = maps:merge(Input, Selected),
|
||||||
case ?RAISE(match_conditions(Conditions, ColumnsAndSelected),
|
case ?RAISE(match_conditions(Conditions, ColumnsAndSelected),
|
||||||
|
emqx_rule_metrics:inc_rules_exception(RuleId),
|
||||||
{match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
{match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
||||||
true ->
|
true ->
|
||||||
ok = emqx_rule_metrics:inc(RuleId, 'rules.matched'),
|
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)
|
||||||
|
end,
|
||||||
{ok, [take_actions(Actions, Coll, Input, OnFailed) || Coll <- Collection2]};
|
{ok, [take_actions(Actions, Coll, Input, OnFailed) || Coll <- Collection2]};
|
||||||
false ->
|
false ->
|
||||||
|
ok = emqx_rule_metrics:inc_rules_no_result(RuleId),
|
||||||
{error, nomatch}
|
{error, nomatch}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -107,14 +114,17 @@ do_apply_rule(#rule{id = RuleId,
|
||||||
conditions = Conditions,
|
conditions = Conditions,
|
||||||
on_action_failed = OnFailed,
|
on_action_failed = OnFailed,
|
||||||
actions = Actions}, Input) ->
|
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_}}),
|
{select_and_transform_error, {_EXCLASS_,_EXCPTION_,_ST_}}),
|
||||||
case ?RAISE(match_conditions(Conditions, maps:merge(Input, Selected)),
|
case ?RAISE(match_conditions(Conditions, maps:merge(Input, Selected)),
|
||||||
|
emqx_rule_metrics:inc_rules_exception(RuleId),
|
||||||
{match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
{match_conditions_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
||||||
true ->
|
true ->
|
||||||
ok = emqx_rule_metrics:inc(RuleId, 'rules.matched'),
|
ok = emqx_rule_metrics:inc_rules_passed(RuleId),
|
||||||
{ok, take_actions(Actions, Selected, Input, OnFailed)};
|
{ok, take_actions(Actions, Selected, Input, OnFailed)};
|
||||||
false ->
|
false ->
|
||||||
|
ok = emqx_rule_metrics:inc_rules_no_result(RuleId),
|
||||||
{error, nomatch}
|
{error, nomatch}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -166,16 +176,18 @@ select_and_collect([Field|More], Input, {Output, LastKV}) ->
|
||||||
{nested_put(Key, Val, Output), LastKV}).
|
{nested_put(Key, Val, Output), LastKV}).
|
||||||
|
|
||||||
%% Filter each item got from FOREACH
|
%% Filter each item got from FOREACH
|
||||||
-dialyzer({nowarn_function, filter_collection/4}).
|
-dialyzer({nowarn_function, filter_collection/5}).
|
||||||
filter_collection(Input, InCase, DoEach, {CollKey, CollVal}) ->
|
filter_collection(RuleId, Input, InCase, DoEach, {CollKey, CollVal}) ->
|
||||||
lists:filtermap(
|
lists:filtermap(
|
||||||
fun(Item) ->
|
fun(Item) ->
|
||||||
InputAndItem = maps:merge(Input, #{CollKey => Item}),
|
InputAndItem = maps:merge(Input, #{CollKey => Item}),
|
||||||
case ?RAISE(match_conditions(InCase, InputAndItem),
|
case ?RAISE(match_conditions(InCase, InputAndItem),
|
||||||
|
emqx_rule_metrics:inc_rules_exception(RuleId),
|
||||||
{match_incase_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
{match_incase_error, {_EXCLASS_,_EXCPTION_,_ST_}}) of
|
||||||
true when DoEach == [] -> {true, InputAndItem};
|
true when DoEach == [] -> {true, InputAndItem};
|
||||||
true ->
|
true ->
|
||||||
{true, ?RAISE(select_and_transform(DoEach, InputAndItem),
|
{true, ?RAISE(select_and_transform(DoEach, InputAndItem),
|
||||||
|
emqx_rule_metrics:inc_rules_exception(RuleId),
|
||||||
{doeach_error, {_EXCLASS_,_EXCPTION_,_ST_}})};
|
{doeach_error, {_EXCLASS_,_EXCPTION_,_ST_}})};
|
||||||
false -> false
|
false -> false
|
||||||
end
|
end
|
||||||
|
|
|
@ -92,9 +92,16 @@ t_rule(_) ->
|
||||||
ok = emqx_rule_metrics:create_rule_metrics(<<"rule:1">>),
|
ok = emqx_rule_metrics:create_rule_metrics(<<"rule:1">>),
|
||||||
ok = emqx_rule_metrics:create_rule_metrics(<<"rule2">>),
|
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.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'),
|
||||||
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.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(2, emqx_rule_metrics:get(<<"rule2">>, 'rules.matched')),
|
||||||
?assertEqual(0, emqx_rule_metrics:get(<<"rule3">>, 'rules.matched')),
|
?assertEqual(0, emqx_rule_metrics:get(<<"rule3">>, 'rules.matched')),
|
||||||
?assertEqual(3, emqx_rule_metrics:get_overall('rules.matched')),
|
?assertEqual(3, emqx_rule_metrics:get_overall('rules.matched')),
|
||||||
|
|
Loading…
Reference in New Issue