Merge pull request #8027 from thalesmg/telemetry-uuid-file

feat(telemetry): save uuids to files
This commit is contained in:
Thales Macedo Garitezi 2022-05-24 16:55:09 -03:00 committed by GitHub
commit 0333e6f860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 127 additions and 4 deletions

View File

@ -93,6 +93,9 @@
-define(TELEMETRY_SHARD, emqx_telemetry_shard). -define(TELEMETRY_SHARD, emqx_telemetry_shard).
-define(NODE_UUID_FILENAME, "node.uuid").
-define(CLUSTER_UUID_FILENAME, "cluster.uuid").
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% API %% API
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -531,7 +534,11 @@ ensure_uuids() ->
NodeUUID = NodeUUID =
case mnesia:wread({?TELEMETRY, node()}) of case mnesia:wread({?TELEMETRY, node()}) of
[] -> [] ->
NodeUUID0 = generate_uuid(), NodeUUID0 =
case get_uuid_from_file(node) of
{ok, NUUID} -> NUUID;
undefined -> generate_uuid()
end,
mnesia:write( mnesia:write(
?TELEMETRY, ?TELEMETRY,
#telemetry{ #telemetry{
@ -547,7 +554,11 @@ ensure_uuids() ->
ClusterUUID = ClusterUUID =
case mnesia:wread({?TELEMETRY, ?CLUSTER_UUID_KEY}) of case mnesia:wread({?TELEMETRY, ?CLUSTER_UUID_KEY}) of
[] -> [] ->
ClusterUUID0 = generate_uuid(), ClusterUUID0 =
case get_uuid_from_file(cluster) of
{ok, CUUID} -> CUUID;
undefined -> generate_uuid()
end,
mnesia:write( mnesia:write(
?TELEMETRY, ?TELEMETRY,
#telemetry{ #telemetry{
@ -562,8 +573,35 @@ ensure_uuids() ->
end, end,
{NodeUUID, ClusterUUID} {NodeUUID, ClusterUUID}
end, end,
{atomic, UUIDs} = mria:transaction(?TELEMETRY_SHARD, Txn), {atomic, {NodeUUID, ClusterUUID}} = mria:transaction(?TELEMETRY_SHARD, Txn),
UUIDs. save_uuid_to_file(NodeUUID, node),
save_uuid_to_file(ClusterUUID, cluster),
{NodeUUID, ClusterUUID}.
get_uuid_from_file(Type) ->
Path = uuid_file_path(Type),
case file:read_file(Path) of
{ok,
UUID =
<<_:8/binary, "-", _:4/binary, "-", _:4/binary, "-", _:4/binary, "-", _:12/binary>>} ->
{ok, UUID};
_ ->
undefined
end.
save_uuid_to_file(UUID, Type) when is_binary(UUID) ->
Path = uuid_file_path(Type),
ok = filelib:ensure_dir(Path),
ok = file:write_file(Path, UUID).
uuid_file_path(Type) ->
DataDir = emqx:data_dir(),
Filename =
case Type of
node -> ?NODE_UUID_FILENAME;
cluster -> ?CLUSTER_UUID_FILENAME
end,
filename:join(DataDir, Filename).
empty_state() -> empty_state() ->
#state{ #state{

View File

@ -151,6 +151,41 @@ init_per_testcase(t_cluster_uuid, Config) ->
Node = start_slave(n1), Node = start_slave(n1),
ok = setup_slave(Node), ok = setup_slave(Node),
[{n1, Node} | Config]; [{n1, Node} | Config];
init_per_testcase(t_uuid_restored_from_file, Config) ->
mock_httpc(),
NodeUUID = <<"AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE">>,
ClusterUUID = <<"FFFFFFFF-GGGG-HHHH-IIII-JJJJJJJJJJJJ">>,
DataDir = emqx:data_dir(),
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
file:delete(NodeUUIDFile),
file:delete(ClusterUUIDFile),
ok = file:write_file(NodeUUIDFile, NodeUUID),
ok = file:write_file(ClusterUUIDFile, ClusterUUID),
%% clear the UUIDs in the DB
{atomic, ok} = mria:clear_table(emqx_telemetry),
emqx_common_test_helpers:stop_apps([emqx_conf, emqx_authn, emqx_authz, emqx_modules]),
emqx_common_test_helpers:start_apps(
[emqx_conf, emqx_authn, emqx_authz, emqx_modules],
fun set_special_configs/1
),
Node = start_slave(n1),
ok = setup_slave(Node),
[
{n1, Node},
{node_uuid, NodeUUID},
{cluster_uuid, ClusterUUID}
| Config
];
init_per_testcase(t_uuid_saved_to_file, Config) ->
mock_httpc(),
DataDir = emqx:data_dir(),
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
file:delete(NodeUUIDFile),
file:delete(ClusterUUIDFile),
Config;
init_per_testcase(t_num_clients, Config) -> init_per_testcase(t_num_clients, Config) ->
mock_httpc(), mock_httpc(),
ok = snabbkaffe:start_trace(), ok = snabbkaffe:start_trace(),
@ -213,6 +248,14 @@ end_per_testcase(t_num_clients, Config) ->
meck:unload([httpc]), meck:unload([httpc]),
ok = snabbkaffe:stop(), ok = snabbkaffe:stop(),
Config; Config;
end_per_testcase(t_uuid_restored_from_file, _Config) ->
DataDir = emqx:data_dir(),
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
ok = file:delete(NodeUUIDFile),
ok = file:delete(ClusterUUIDFile),
meck:unload([httpc]),
ok;
end_per_testcase(_Testcase, _Config) -> end_per_testcase(_Testcase, _Config) ->
meck:unload([httpc]), meck:unload([httpc]),
ok. ok.
@ -248,6 +291,48 @@ t_cluster_uuid(Config) ->
?assertNotEqual(NodeUUID0, NodeUUID1), ?assertNotEqual(NodeUUID0, NodeUUID1),
ok. ok.
%% should attempt read UUID from file in data dir to keep UUIDs
%% unique, in the event of a database purge.
t_uuid_restored_from_file(Config) ->
ExpectedNodeUUID = ?config(node_uuid, Config),
ExpectedClusterUUID = ?config(cluster_uuid, Config),
?assertEqual(
{ok, ExpectedNodeUUID},
emqx_telemetry:get_node_uuid()
),
?assertEqual(
{ok, ExpectedClusterUUID},
emqx_telemetry:get_cluster_uuid()
),
ok.
t_uuid_saved_to_file(_Config) ->
DataDir = emqx:data_dir(),
NodeUUIDFile = filename:join(DataDir, "node.uuid"),
ClusterUUIDFile = filename:join(DataDir, "cluster.uuid"),
%% preconditions
?assertEqual({error, enoent}, file:read_file(NodeUUIDFile)),
?assertEqual({error, enoent}, file:read_file(ClusterUUIDFile)),
%% clear the UUIDs in the DB
{atomic, ok} = mria:clear_table(emqx_telemetry),
emqx_common_test_helpers:stop_apps([emqx_conf, emqx_authn, emqx_authz, emqx_modules]),
emqx_common_test_helpers:start_apps(
[emqx_conf, emqx_authn, emqx_authz, emqx_modules],
fun set_special_configs/1
),
{ok, NodeUUID} = emqx_telemetry:get_node_uuid(),
{ok, ClusterUUID} = emqx_telemetry:get_cluster_uuid(),
?assertEqual(
{ok, NodeUUID},
file:read_file(NodeUUIDFile)
),
?assertEqual(
{ok, ClusterUUID},
file:read_file(ClusterUUIDFile)
),
ok.
t_official_version(_) -> t_official_version(_) ->
true = emqx_telemetry:official_version("0.0.0"), true = emqx_telemetry:official_version("0.0.0"),
true = emqx_telemetry:official_version("1.1.1"), true = emqx_telemetry:official_version("1.1.1"),