From 72b87a6a7e10c6c4511c08a32912e5bcd89742bb Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Wed, 6 Apr 2022 14:29:07 -0300 Subject: [PATCH 1/2] feat(exhook): export basic usage info for telemetry --- apps/emqx_exhook/src/emqx_exhook.erl | 39 +++++++++++++++++++++ apps/emqx_exhook/test/emqx_exhook_SUITE.erl | 32 +++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/apps/emqx_exhook/src/emqx_exhook.erl b/apps/emqx_exhook/src/emqx_exhook.erl index 1539dfdf1..288bad9f2 100644 --- a/apps/emqx_exhook/src/emqx_exhook.erl +++ b/apps/emqx_exhook/src/emqx_exhook.erl @@ -23,6 +23,9 @@ , call_fold/3 ]). +%% exported for `emqx_telemetry' +-export([get_basic_usage_info/0]). + %%-------------------------------------------------------------------- %% Dispatch APIs %%-------------------------------------------------------------------- @@ -81,3 +84,39 @@ deny_action_result('message.publish', Msg) -> %% TODO: Not support to deny a message %% maybe we can put the 'allow_publish' into message header Msg. + +%%-------------------------------------------------------------------- +%% APIs for `emqx_telemetry' +%%-------------------------------------------------------------------- + +-spec get_basic_usage_info() -> + #{ num_servers => non_neg_integer() + , servers => + [#{ driver => Driver + , hooks => [emqx_exhook_server:hookpoint()] + }] + } when Driver :: grpc. +get_basic_usage_info() -> + try + Servers = emqx_exhook_mgr:running(), + NumServers = length(Servers), + ServerInfo = + lists:map( + fun(ServerName) -> + Hooks = emqx_exhook_mgr:hooks(ServerName), + HookNames = lists:map(fun(#{name := Name}) -> Name end, Hooks), + #{ hooks => HookNames + , %% currently, only grpc driver exists. + driver => grpc + } + end, + Servers), + #{ num_servers => NumServers + , servers => ServerInfo + } + catch + _:_ -> + #{ num_servers => 0 + , servers => [] + } + end. diff --git a/apps/emqx_exhook/test/emqx_exhook_SUITE.erl b/apps/emqx_exhook/test/emqx_exhook_SUITE.erl index 543f0b9fc..5af8606a7 100644 --- a/apps/emqx_exhook/test/emqx_exhook_SUITE.erl +++ b/apps/emqx_exhook/test/emqx_exhook_SUITE.erl @@ -231,6 +231,38 @@ t_misc_test(_) -> _ = emqx_exhook_server:format(#{name => <<"test">>, hookspec => #{}}), ok. +t_get_basic_usage_info(_Config) -> + #{ num_servers := NumServers + , servers := Servers + } = emqx_exhook:get_basic_usage_info(), + ?assertEqual(1, NumServers), + ?assertMatch([_], Servers), + [#{driver := Driver, hooks := Hooks}] = Servers, + ?assertEqual(grpc, Driver), + ?assertEqual( + [ + 'client.authenticate', + 'client.authorize', + 'client.connack', + 'client.connect', + 'client.connected', + 'client.disconnected', + 'client.subscribe', + 'client.unsubscribe', + 'message.acked', + 'message.delivered', + 'message.dropped', + 'message.publish', + 'session.created', + 'session.discarded', + 'session.resumed', + 'session.subscribed', + 'session.takenover', + 'session.terminated', + 'session.unsubscribed' + ], + lists:sort(Hooks)). + %%-------------------------------------------------------------------- %% Utils %%-------------------------------------------------------------------- From 6eed6e45c21e5c54c66045279f5357342db7c492 Mon Sep 17 00:00:00 2001 From: Thales Macedo Garitezi Date: Wed, 6 Apr 2022 14:29:40 -0300 Subject: [PATCH 2/2] feat(telemetry): report basic exhook usage --- apps/emqx_modules/src/emqx_telemetry.erl | 6 +- .../test/emqx_telemetry_SUITE.erl | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/apps/emqx_modules/src/emqx_telemetry.erl b/apps/emqx_modules/src/emqx_telemetry.erl index a89c4ce2f..38966b854 100644 --- a/apps/emqx_modules/src/emqx_telemetry.erl +++ b/apps/emqx_modules/src/emqx_telemetry.erl @@ -349,7 +349,8 @@ get_telemetry(State0 = #state{uuid = UUID}) -> {authn_authz, get_authn_authz_info()}, {gateway, get_gateway_info()}, {rule_engine, RuleEngineInfo}, - {bridge, BridgeInfo} + {bridge, BridgeInfo}, + {exhook, get_exhook_info()} ]}. report_telemetry(State0 = #state{url = URL}) -> @@ -505,6 +506,9 @@ get_rule_engine_and_bridge_info() -> } }. +get_exhook_info() -> + emqx_exhook:get_basic_usage_info(). + bin(L) when is_list(L) -> list_to_binary(L); bin(A) when is_atom(A) -> diff --git a/apps/emqx_modules/test/emqx_telemetry_SUITE.erl b/apps/emqx_modules/test/emqx_telemetry_SUITE.erl index beaa9ccb2..fd04d5224 100644 --- a/apps/emqx_modules/test/emqx_telemetry_SUITE.erl +++ b/apps/emqx_modules/test/emqx_telemetry_SUITE.erl @@ -123,6 +123,26 @@ init_per_testcase(t_rule_engine_and_data_bridge_info, Config) -> ok = emqx_bridge_SUITE:setup_fake_telemetry_data(), ok = setup_fake_rule_engine_data(), Config; +init_per_testcase(t_exhook_info, Config) -> + mock_httpc(), + {ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000), + ExhookConf = + #{ + <<"exhook">> => + #{ + <<"servers">> => + [ + #{ + <<"name">> => "myhook", + <<"url">> => "http://127.0.0.1:9000" + } + ] + } + }, + {ok, _} = emqx_exhook_demo_svr:start(), + ok = emqx_common_test_helpers:load_config(emqx_exhook_schema, ExhookConf), + {ok, _} = application:ensure_all_started(emqx_exhook), + Config; init_per_testcase(_Testcase, Config) -> TestPID = self(), ok = meck:new(httpc, [non_strict, passthrough, no_history, no_link]), @@ -169,6 +189,11 @@ end_per_testcase(t_rule_engine_and_data_bridge_info, _Config) -> ] ), ok; +end_per_testcase(t_exhook_info, _Config) -> + meck:unload(httpc), + emqx_exhook_demo_svr:stop(), + application:stop(emqx_exhook), + ok; end_per_testcase(_Testcase, _Config) -> meck:unload([httpc]), ok. @@ -391,6 +416,39 @@ t_rule_engine_and_data_bridge_info(_Config) -> ), ok. +t_exhook_info(_Config) -> + {ok, TelemetryData} = emqx_telemetry:get_telemetry(), + ExhookInfo = get_value(exhook, TelemetryData), + ?assertEqual(1, maps:get(num_servers, ExhookInfo)), + [Server] = maps:get(servers, ExhookInfo), + ?assertEqual(grpc, maps:get(driver, Server)), + Hooks = maps:get(hooks, Server), + ?assertEqual( + [ + 'client.authenticate', + 'client.authorize', + 'client.connack', + 'client.connect', + 'client.connected', + 'client.disconnected', + 'client.subscribe', + 'client.unsubscribe', + 'message.acked', + 'message.delivered', + 'message.dropped', + 'message.publish', + 'session.created', + 'session.discarded', + 'session.resumed', + 'session.subscribed', + 'session.takenover', + 'session.terminated', + 'session.unsubscribed' + ], + lists:sort(Hooks) + ), + ok. + assert_approximate(Map, Key, Expected) -> Value = maps:get(Key, Map), ?assertEqual(Expected, float_to_list(Value, [{decimals, 2}])).