From 8354095e4bbc6ae42f04ffcd5e620a103e6d41b5 Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Mon, 4 Apr 2022 16:14:42 -0300 Subject: [PATCH] feat(rules): export basic usage info for telemetry --- .../emqx_rule_engine/src/emqx_rule_engine.erl | 53 +++++++++++++++++++ .../test/emqx_rule_engine_SUITE.erl | 41 ++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine.erl b/apps/emqx_rule_engine/src/emqx_rule_engine.erl index 1bf0088fe..f42094b0c 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine.erl @@ -58,6 +58,9 @@ , clear_metrics_for_rule/1 ]). +%% exported for `emqx_telemetry' +-export([get_basic_usage_info/0]). + %% gen_server Callbacks -export([ init/1 , handle_call/3 @@ -201,6 +204,56 @@ unload_hooks_for_rule(#{id := Id, from := Topics}) -> end end, Topics). +%%------------------------------------------------------------------------------ +%% Telemetry helper functions +%%------------------------------------------------------------------------------ + +-spec get_basic_usage_info() -> #{ num_rules => non_neg_integer() + , referenced_bridges => + #{ BridgeType => non_neg_integer() + } + } + when BridgeType :: atom(). +get_basic_usage_info() -> + try + Rules = get_rules(), + EnabledRules = + lists:filter( + fun(#{enable := Enabled}) -> Enabled end, + Rules), + NumRules = length(EnabledRules), + ReferencedBridges = + lists:foldl( + fun(#{outputs := Outputs}, Acc) -> + BridgeIDs = lists:filter(fun is_binary/1, Outputs), + tally_referenced_bridges(BridgeIDs, Acc) + end, + #{}, + EnabledRules), + #{ num_rules => NumRules + , referenced_bridges => ReferencedBridges + } + catch + _:_ -> + #{ num_rules => 0 + , referenced_bridges => #{} + } + end. + + +tally_referenced_bridges(BridgeIDs, Acc0) -> + lists:foldl( + fun(BridgeID, Acc) -> + {BridgeType, _BridgeName} = emqx_bridge:parse_bridge_id(BridgeID), + maps:update_with( + BridgeType, + fun(X) -> X + 1 end, + 1, + Acc) + end, + Acc0, + BridgeIDs). + %%------------------------------------------------------------------------------ %% gen_server callbacks %%------------------------------------------------------------------------------ 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 8254e182c..ab5a34f13 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_SUITE.erl @@ -1356,6 +1356,47 @@ t_sqlparse_nested_get(_Config) -> payload => <<"{\"a\": {\"b\": 0}}">> }})). +%%------------------------------------------------------------------------------ +%% Test cases for telemetry functions +%%------------------------------------------------------------------------------ + +t_get_basic_usage_info_0(_Config) -> + ?assertEqual( + #{ num_rules => 0 + , referenced_bridges => #{} + }, + emqx_rule_engine:get_basic_usage_info()), + ok. + +t_get_basic_usage_info_1(_Config) -> + {ok, _} = + emqx_rule_engine:create_rule( + #{id => <<"rule:t_get_basic_usage_info:1">>, + sql => <<"select 1 from topic">>, + outputs => + [ #{function => <<"erlang:hibernate">>, args => #{}} + , #{function => console} + , <<"http:my_http_bridge">> + , <<"http:my_http_bridge">> + ]}), + {ok, _} = + emqx_rule_engine:create_rule( + #{id => <<"rule:t_get_basic_usage_info:2">>, + sql => <<"select 1 from topic">>, + outputs => + [ <<"mqtt:my_mqtt_bridge">> + , <<"http:my_http_bridge">> + ]}), + ?assertEqual( + #{ num_rules => 2 + , referenced_bridges => + #{ mqtt => 1 + , http => 3 + } + }, + emqx_rule_engine:get_basic_usage_info()), + ok. + %%------------------------------------------------------------------------------ %% Internal helpers %%------------------------------------------------------------------------------