feat(telemetry): Update the configuration file to hocon (#5064)

This commit is contained in:
turtleDeng 2021-06-23 17:12:24 +08:00 committed by zhanghongtong
parent 39e4d348f6
commit b4d9af0e85
13 changed files with 58 additions and 192 deletions

View File

@ -101,16 +101,6 @@
, delete_banned/1
]).
-ifndef(EMQX_ENTERPRISE).
-export([ enable_telemetry/0
, disable_telemetry/0
, get_telemetry_status/0
, get_telemetry_data/0
]).
-endif.
%% Common Table API
-export([ item/2
, max_row_limit/0
@ -498,38 +488,6 @@ create_banned(Banned) ->
delete_banned(Who) ->
emqx_banned:delete(Who).
%%--------------------------------------------------------------------
%% Telemtry API
%%--------------------------------------------------------------------
-ifndef(EMQX_ENTERPRISE).
enable_telemetry() ->
lists:foreach(fun enable_telemetry/1,ekka_mnesia:running_nodes()).
enable_telemetry(Node) when Node =:= node() ->
emqx_telemetry:enable();
enable_telemetry(Node) ->
rpc_call(Node, enable_telemetry, [Node]).
disable_telemetry() ->
lists:foreach(fun disable_telemetry/1,ekka_mnesia:running_nodes()).
disable_telemetry(Node) when Node =:= node() ->
emqx_telemetry:disable();
disable_telemetry(Node) ->
rpc_call(Node, disable_telemetry, [Node]).
get_telemetry_status() ->
[{enabled, emqx_telemetry:is_enabled()}].
get_telemetry_data() ->
emqx_telemetry:get_telemetry().
-endif.
%%--------------------------------------------------------------------
%% Common Table API
%%--------------------------------------------------------------------

View File

@ -1,28 +1,3 @@
##--------------------------------------------------------------------
## Telemetry
##--------------------------------------------------------------------
## Enable telemetry
##
## Value: true | false
##
## Default: true
telemetry.enabled = true
## The destination URL for the telemetry data report
##
## Value: String
##
## Default: "https://telemetry.emqx.io/api/telemetry"
telemetry.url = "https://telemetry.emqx.io/api/telemetry"
## Interval for reporting telemetry data
##
## Value: Duration
## -d: day
## -h: hour
## -m: minute
## -s: second
##
## Default: 7d
telemetry.report_interval = 7d
emqx_telemetry:{
enabled: true
}

View File

@ -0,0 +1,5 @@
%% The destination URL for the telemetry data report
-define(TELEMETRY_URL, "https://telemetry.emqx.io/api/telemetry").
%% Interval for reporting telemetry data, Default: 7d
-define(REPORT_INTERVAR, 604800).

View File

@ -1,17 +0,0 @@
%%-*- mode: erlang -*-
%% Retainer config mapping
{mapping, "telemetry.enabled", "emqx_telemetry.enabled", [
{default, true},
{datatype, {enum, [true, false]}}
]}.
{mapping, "telemetry.url", "emqx_telemetry.url", [
{default, "https://telemetry.emqx.io/api/telemetry"},
{datatype, string}
]}.
{mapping, "telemetry.report_interval", "emqx_telemetry.report_interval", [
{default, "7d"},
{datatype, {duration, s}}
]}.

View File

@ -1,6 +1,6 @@
{application, emqx_telemetry,
[{description, "EMQ X Telemetry"},
{vsn, "4.3.1"}, % strict semver, bump manually!
{vsn, "5.0.0"}, % strict semver, bump manually!
{modules, []},
{registered, [emqx_telemetry_sup]},
{applications, [kernel,stdlib]},

View File

@ -1,15 +0,0 @@
%% -*- mode: erlang -*-
{VSN,
[
{"4.3.0", [
{load_module, emqx_telemetry, brutal_purge, soft_purge, []}
]},
{<<".*">>, []}
],
[
{"4.3.0", [
{load_module, emqx_telemetry, brutal_purge, soft_purge, []}
]},
{<<".*">>, []}
]
}.

View File

@ -24,7 +24,7 @@
-include_lib("kernel/include/file.hrl").
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
-logger_header("[Telemetry]").
-include("emqx_telemetry.hrl").
%% Mnesia bootstrap
-export([mnesia/1]).
@ -82,7 +82,7 @@
timer = undefined :: undefined | reference()
}).
%% The count of 100-nanosecond intervals between the UUID epoch
%% The count of 100-nanosecond intervals between the UUID epoch
%% 1582-10-15 00:00:00 and the UNIX epoch 1970-01-01 00:00:00.
-define(GREGORIAN_EPOCH_OFFSET, 16#01b21dd213814000).
@ -140,16 +140,11 @@ get_telemetry() ->
%% is very small, it should be safe to ignore.
-dialyzer([{nowarn_function, [init/1]}]).
init([Opts]) ->
State = #state{url = get_value(url, Opts),
report_interval = timer:seconds(get_value(report_interval, Opts))},
State = #state{url = ?TELEMETRY_URL,
report_interval = timer:seconds(?REPORT_INTERVAR)},
NState = case mnesia:dirty_read(?TELEMETRY, ?UNIQUE_ID) of
[] ->
Enabled = case search_telemetry_enabled() of
{error, not_found} ->
get_value(enabled, Opts);
{M, F} ->
erlang:apply(M, F, [])
end,
Enabled = proplists:get_value(enabled, Opts, true),
UUID = generate_uuid(),
mnesia:dirty_write(?TELEMETRY, #telemetry{id = ?UNIQUE_ID,
uuid = UUID,
@ -237,14 +232,6 @@ official_version(Version) ->
ensure_report_timer(State = #state{report_interval = ReportInterval}) ->
State#state{timer = emqx_misc:start_timer(ReportInterval, time_to_report_telemetry_data)}.
license() ->
case search_telemetry_license() of
{error, not_found} ->
[{edition, <<"community">>}];
{M, F} ->
erlang:apply(M, F, [])
end.
os_info() ->
case erlang:system_info(os_type) of
{unix,darwin} ->
@ -348,7 +335,7 @@ generate_uuid() ->
get_telemetry(#state{uuid = UUID}) ->
OSInfo = os_info(),
[{emqx_version, bin(emqx_app:get_release())},
{license, license()},
{license, [{edition, <<"community">>}]},
{os_name, bin(get_value(os_name, OSInfo))},
{os_version, bin(get_value(os_version, OSInfo))},
{otp_version, bin(otp_version())},
@ -375,58 +362,6 @@ report_telemetry(State = #state{url = URL}) ->
httpc_request(Method, URL, Headers, Body) ->
httpc:request(Method, {URL, Headers, "application/json", Body}, [], []).
ignore_lib_apps(Apps) ->
LibApps = [kernel, stdlib, sasl, appmon, eldap, erts,
syntax_tools, ssl, crypto, mnesia, os_mon,
inets, goldrush, gproc, runtime_tools,
snmp, otp_mibs, public_key, asn1, ssh, hipe,
common_test, observer, webtool, xmerl, tools,
test_server, compiler, debugger, eunit, et,
wx],
[AppName || {AppName, _, _} <- Apps, not lists:member(AppName, LibApps)].
search_telemetry_license() ->
search_function(telemetry_license).
search_telemetry_enabled() ->
search_function(telemetry_enabled).
search_function(Name) ->
case search_attrs(Name) of
[] ->
{error, not_found};
Callbacks ->
case lists:filter(fun({M, F}) ->
erlang:function_exported(M, F, 0)
end, Callbacks) of
[] -> {error, not_found};
[{M, F} | _] -> {M, F}
end
end.
search_attrs(Name) ->
Apps = ignore_lib_apps(application:loaded_applications()),
search_attrs(Name, Apps).
search_attrs(Name, Apps) ->
lists:foldl(fun(App, Acc) ->
{ok, Modules} = application:get_key(App, modules),
Attrs = lists:foldl(fun(Module, Acc0) ->
case proplists:get_value(Name, module_attributes(Module), undefined) of
undefined -> Acc0;
Attrs0 -> Acc0 ++ Attrs0
end
end, [], Modules),
Acc ++ Attrs
end, [], Apps).
module_attributes(Module) ->
try Module:module_info(attributes)
catch
error:undef -> [];
error:Reason -> error(Reason)
end.
bin(L) when is_list(L) ->
list_to_binary(L);
bin(B) when is_binary(B) ->

View File

@ -51,15 +51,15 @@
%%--------------------------------------------------------------------
cli(["enable"]) ->
emqx_mgmt:enable_telemetry(),
enable_telemetry(),
emqx_ctl:print("Enable telemetry successfully~n");
cli(["disable"]) ->
emqx_mgmt:disable_telemetry(),
disable_telemetry(),
emqx_ctl:print("Disable telemetry successfully~n");
cli(["get", "status"]) ->
case emqx_mgmt:get_telemetry_status() of
case get_telemetry_status() of
[{enabled, true}] ->
emqx_ctl:print("Telemetry is enabled~n");
[{enabled, false}] ->
@ -67,7 +67,7 @@ cli(["get", "status"]) ->
end;
cli(["get", "data"]) ->
{ok, TelemetryData} = emqx_mgmt:get_telemetry_data(),
{ok, TelemetryData} = get_telemetry_data(),
case emqx_json:safe_encode(TelemetryData, [pretty]) of
{ok, Bin} ->
emqx_ctl:print("~s~n", [Bin]);
@ -97,7 +97,7 @@ enable(_Bindings, Params) ->
end.
get_status(_Bindings, _Params) ->
return(get_telemetry_status()).
return({ok, get_telemetry_status()}).
get_data(_Bindings, _Params) ->
return(get_telemetry_data()).
@ -119,7 +119,7 @@ disable_telemetry(Node) ->
rpc_call(Node, ?MODULE, disable_telemetry, [Node]).
get_telemetry_status() ->
{ok, [{enabled, emqx_telemetry:is_enabled()}]}.
[{enabled, emqx_telemetry:is_enabled()}].
get_telemetry_data() ->
emqx_telemetry:get_telemetry().

View File

@ -18,16 +18,22 @@
-behaviour(application).
-emqx_plugin(?MODULE).
-define(APP, emqx_telemetry).
-export([ start/2
, stop/1
]).
start(_Type, _Args) ->
emqx_ctl:register_command(telemetry, {emqx_telemetry_api, cli}),
Env = application:get_all_env(emqx_telemetry),
emqx_telemetry_sup:start_link(Env).
%% TODO
%% After the relevant code for building hocon configuration will be deleted
%% Get the configuration using emqx_config:get
ConfFile = filename:join([emqx:get_env(plugins_etc_dir), ?APP]) ++ ".conf",
{ok, RawConfig} = hocon:load(ConfFile),
Config = hocon_schema:check_plain(emqx_telemetry_schema, RawConfig, #{atom_key => true}),
emqx_config_handler:update_config(emqx_config_handler, Config),
Enabled = emqx_config:get([?APP, enabled], true),
emqx_telemetry_sup:start_link([{enabled, Enabled}]).
stop(_State) ->
emqx_ctl:unregister_command(telemetry),

View File

@ -0,0 +1,13 @@
-module(emqx_telemetry_schema).
-include_lib("typerefl/include/types.hrl").
-behaviour(hocon_schema).
-export([ structs/0
, fields/1]).
structs() -> ["emqx_telemetry"].
fields("emqx_telemetry") ->
[{enabled, emqx_schema:t(boolean(), undefined, false)}].

View File

@ -29,11 +29,20 @@ all() -> emqx_ct:all(?MODULE).
init_per_testcase(_, Config) ->
emqx_ct_helpers:boot_modules(all),
emqx_ct_helpers:start_apps([emqx_modules, emqx_telemetry]),
emqx_ct_helpers:start_apps([emqx_telemetry], fun set_special_configs/1),
Config.
end_per_testcase(_, _Config) ->
emqx_ct_helpers:stop_apps([emqx_telemetry, emqx_modules]).
emqx_ct_helpers:stop_apps([emqx_telemetry]).
set_special_configs(emqx_telemetry) ->
application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_telemetry, "test")),
Conf = #{<<"emqx_telemetry">> => #{<<"enabled">> => true}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_telemetry.conf'), jsx:encode(Conf)),
ok;
set_special_configs(_App) ->
ok.
t_uuid(_) ->
UUID = emqx_telemetry:generate_uuid(),
@ -41,9 +50,7 @@ t_uuid(_) ->
?assertEqual(5, length(Parts)),
{ok, UUID2} = emqx_telemetry:get_uuid(),
emqx_telemetry:stop(),
emqx_telemetry:start_link([{enabled, true},
{url, "https://telemetry.emqx.io/api/telemetry"},
{report_interval, 7 * 24 * 60 * 60}]),
emqx_telemetry:start_link([{enabled, true}]),
{ok, UUID3} = emqx_telemetry:get_uuid(),
?assertEqual(UUID2, UUID3).

View File

@ -3,6 +3,5 @@
{emqx_modules, {{enable_plugin_emqx_modules}}}.
{emqx_recon, {{enable_plugin_emqx_recon}}}.
{emqx_retainer, {{enable_plugin_emqx_retainer}}}.
{emqx_telemetry, {{enable_plugin_emqx_telemetry}}}.
{emqx_rule_engine, {{enable_plugin_emqx_rule_engine}}}.
{emqx_bridge_mqtt, {{enable_plugin_emqx_bridge_mqtt}}}.

View File

@ -196,7 +196,6 @@ overlay_vars_rel(RelType) ->
, {enable_plugin_emqx_modules, false} %% modules is not a plugin in ce
, {enable_plugin_emqx_recon, true}
, {enable_plugin_emqx_retainer, true}
, {enable_plugin_emqx_telemetry, true}
, {vm_args_file, VmArgs}
].
@ -256,6 +255,7 @@ relx_apps(ReleaseType) ->
, emqx_connector
, emqx_data_bridge
]
++ [emqx_telemetry || not is_enterprise()]
++ [emqx_modules || not is_enterprise()]
++ [emqx_license || is_enterprise()]
++ [bcrypt || provide_bcrypt_release(ReleaseType)]
@ -296,7 +296,6 @@ relx_plugin_apps(ReleaseType) ->
, emqx_sasl
, emqx_statsd
]
++ [emqx_telemetry || not is_enterprise()]
++ relx_plugin_apps_per_rel(ReleaseType)
++ relx_plugin_apps_enterprise(is_enterprise())
++ relx_plugin_apps_extra().
@ -387,6 +386,7 @@ emqx_etc_overlay_common() ->
{"{{base_dir}}/lib/emqx/etc/emqx.conf", "etc/emqx.conf"},
{"{{base_dir}}/lib/emqx/etc/ssl_dist.conf", "etc/ssl_dist.conf"},
{"{{base_dir}}/lib/emqx_data_bridge/etc/emqx_data_bridge.conf", "etc/plugins/emqx_data_bridge.conf"},
{"{{base_dir}}/lib/emqx_telemetry/etc/emqx_telemetry.conf", "etc/plugins/emqx_telemetry.conf"},
{"{{base_dir}}/lib/emqx_authz/etc/emqx_authz.conf", "etc/plugins/authz.conf"},
%% TODO: check why it has to end with .paho
%% and why it is put to etc/plugins dir