From f88e63f741dc03edc31cd7da2d40d45c09e1e29d Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Mon, 17 Apr 2023 10:54:49 +0200 Subject: [PATCH 1/6] Changing events format. Sending them to new GA4 instance. --- .../mongoose_system_metrics_collector.erl | 66 +++++++++------ .../mongoose_system_metrics_file.erl | 1 - .../mongoose_system_metrics_sender.erl | 80 +++++++------------ .../service_mongoose_system_metrics.erl | 11 ++- 4 files changed, 76 insertions(+), 82 deletions(-) diff --git a/src/system_metrics/mongoose_system_metrics_collector.erl b/src/system_metrics/mongoose_system_metrics_collector.erl index f643d42139e..c22d7de9a00 100644 --- a/src/system_metrics/mongoose_system_metrics_collector.erl +++ b/src/system_metrics/mongoose_system_metrics_collector.erl @@ -43,11 +43,11 @@ report_getters() -> get_hosts_count() -> HostTypes = ?ALL_HOST_TYPES, NumberOfHosts = length(HostTypes), - [#{report_name => hosts, key => count, value => NumberOfHosts}]. + [#{name => hosts_count, params => #{value => NumberOfHosts}}]. get_domains_count() -> DomainsCount = mongoose_domain_core:domains_count(), - [#{report_name => domains, key => count, value => DomainsCount}]. + [#{name => domains_count, params => #{value => DomainsCount}}]. get_modules() -> HostTypes = ?ALL_HOST_TYPES, @@ -79,10 +79,15 @@ get_modules_metrics(Host, Modules) -> end, Modules). report_module_with_opts(Module, Opts) -> - lists:map( - fun({OptKey, OptValue}) -> - #{report_name => Module, key => OptKey, value => OptValue} - end,Opts). + #{name => module_with_opts, params => + lists:foldl( + fun + ({none, _}, Acc) -> + Acc; + ({OptKey, OptValue}, Acc) -> + maps:put(OptKey, OptValue, Acc) + end, #{module => Module}, Opts) + }. get_number_of_custom_modules() -> HostTypes = ?ALL_HOST_TYPES, @@ -94,23 +99,23 @@ get_number_of_custom_modules() -> mongoose_module_metrics), MetricsModuleSet = sets:from_list(MetricsModule), CountCustomMods= sets:size(sets:subtract(GenModsSet, MetricsModuleSet)), - #{report_name => custom_modules, key => count, value => CountCustomMods}. + #{name => custom_modules_count, params => #{value => CountCustomMods}}. get_uptime() -> {Uptime, _} = statistics(wall_clock), UptimeSeconds = Uptime div 1000, {D, {H, M, S}} = calendar:seconds_to_daystime(UptimeSeconds), Formatted = io_lib:format("~4..0B-~2..0B:~2..0B:~2..0B", [D,H,M,S]), - [#{report_name => cluster, key => uptime, value => list_to_binary(Formatted)}]. + [#{name => cluster_uptime, params => #{value => list_to_binary(Formatted)}}]. get_cluster_size() -> NodesNo = length(nodes()) + 1, - [#{report_name => cluster, key => number_of_nodes, value => NodesNo}]. + [#{name => cluster_size, params => #{value => NodesNo}}]. get_version() -> case lists:keyfind(mongooseim, 1, application:which_applications()) of {_, _, Version} -> - #{report_name => cluster, key => mim_version, value => list_to_binary(Version)}; + #{name => mongooseim_version, params => #{value => list_to_binary(Version)}}; _ -> [] end. @@ -119,11 +124,14 @@ get_components() -> Domains = mongoose_router:get_all_domains() ++ ejabberd_router:dirty_get_all_components(all), Components = [ejabberd_router:lookup_component(D, node()) || D <- Domains], LenComponents = length(lists:flatten(Components)), - #{report_name => cluster, key => number_of_components, value => LenComponents}. + #{name => cluster_components, params => #{value => LenComponents}}. get_api() -> ApiList = filter_unknown_api(get_http_handler_modules()), - [#{report_name => http_api, key => Api, value => enabled} || Api <- ApiList]. + [#{name => http_api, params => + lists:foldl(fun(Element, Acc) -> + maps:put(Element, enabled, Acc) + end, #{}, ApiList)}]. filter_unknown_api(ApiList) -> AllowedToReport = [mongoose_client_api, mongoose_admin_api, mod_bosh, mod_websockets], @@ -133,9 +141,10 @@ get_transport_mechanisms() -> HTTP = [Mod || Mod <- get_http_handler_modules(), Mod =:= mod_bosh orelse Mod =:= mod_websockets], TCP = lists:usort([tcp || #{proto := tcp} <- get_listeners(mongoose_c2s_listener)]), - [#{report_name => transport_mechanism, - key => Transport, - value => enabled} || Transport <- HTTP ++ TCP]. + [#{name => transport_mechanism, + params => lists:foldl(fun(Element, Acc) -> + maps:put(Element, enabled, Acc) + end, #{}, HTTP ++ TCP)}]. get_http_handler_modules() -> Listeners = get_listeners(ejabberd_cowboy), @@ -150,8 +159,10 @@ get_http_handler_modules(#{handlers := Handlers}) -> get_tls_options() -> TLSOptions = lists:flatmap(fun extract_tls_options/1, get_listeners(mongoose_c2s_listener)), - [#{report_name => tls_option, key => TLSMode, value => TLSModule} || - {TLSMode, TLSModule} <- lists:usort(TLSOptions)]. + [#{name => tls_options, + params => lists:foldl(fun({Key, Val}, Acc) -> + maps:put(Key, Val, Acc) + end, #{}, lists:usort(TLSOptions))}]. extract_tls_options(#{tls := #{mode := TLSMode, module := TLSModule}}) -> [{TLSMode, TLSModule}]; @@ -159,18 +170,21 @@ extract_tls_options(_) -> []. get_outgoing_pools() -> OutgoingPools = mongoose_config:get_opt(outgoing_pools), - [#{report_name => outgoing_pools, - key => type, - value => Type} || #{type := Type} <- OutgoingPools]. + [#{name => outgoing_pools, + params => #{key => Type}} || #{type := Type} <- OutgoingPools]. get_xmpp_stanzas_count(PrevReport) -> + io:format("PREV_REPORT: ~p", [PrevReport]), StanzaTypes = [xmppMessageSent, xmppMessageReceived, xmppIqSent, xmppIqReceived, xmppPresenceSent, xmppPresenceReceived], NewCount = [count_stanzas(StanzaType) || StanzaType <- StanzaTypes], StanzasCount = calculate_stanza_rate(PrevReport, NewCount), - [#{report_name => StanzaType, - key => Total, - value => Increment} || {StanzaType, Total, Increment} <- StanzasCount]. + [#{name => xmpp_stanzas_count, + params => #{ + stanza_type => StanzaType, + total => Total, + increment => Increment + }} || {StanzaType, Total, Increment} <- StanzasCount]. count_stanzas(StanzaType) -> ExometerResults = exometer:get_values(['_', StanzaType]), @@ -182,7 +196,9 @@ calculate_stanza_rate([], NewCount) -> [{Type, Count, Count} || {Type, Count} <- NewCount]; calculate_stanza_rate(PrevReport, NewCount) -> ReportProplist = [{Name, Key} || - #{report_name := Name, key := Key} <- PrevReport], + #{name := xmpp_stanzas_count, + params := #{stanza_type := Name, total := Key}} <- PrevReport], + io:format("ReportProplist: ~p\n", [ReportProplist]), [{Type, Count, case proplists:get_value(Type, ReportProplist) of undefined -> Count; @@ -196,4 +212,4 @@ get_config_type() -> ".cfg" -> cfg; _ -> unknown_config_type end, - [#{report_name => cluster, key => config_type, value => ConfigType}]. + [#{name => config_type, params => #{config_type => ConfigType}}]. diff --git a/src/system_metrics/mongoose_system_metrics_file.erl b/src/system_metrics/mongoose_system_metrics_file.erl index b5f0fd74cb8..28b115a06fb 100644 --- a/src/system_metrics/mongoose_system_metrics_file.erl +++ b/src/system_metrics/mongoose_system_metrics_file.erl @@ -15,4 +15,3 @@ save(Reports) -> JSON = jiffy:encode(Reports, [pretty]), file:write_file(location(), JSON), ok. - diff --git a/src/system_metrics/mongoose_system_metrics_sender.erl b/src/system_metrics/mongoose_system_metrics_sender.erl index af0d0a65062..6eb97776798 100644 --- a/src/system_metrics/mongoose_system_metrics_sender.erl +++ b/src/system_metrics/mongoose_system_metrics_sender.erl @@ -1,6 +1,6 @@ -module(mongoose_system_metrics_sender). --define(BASE_URL, "https://www.google-analytics.com/batch"). +-define(BASE_URL, "https://www.google-analytics.com/mp/collect"). -export([send/3]). @@ -11,69 +11,45 @@ -spec send(service_mongoose_system_metrics:client_id(), [report_struct()], [service_mongoose_system_metrics:tracking_id()]) -> ok. -send(ClientId, ReportStructs, TrackingIds) -> - Reports = build_reports_for_each_tracking_id(ClientId, TrackingIds, ReportStructs), - send_reports(Reports), +send(ClientId, Reports, TrackingIds) -> + io:format("\nReports: ~p", [Reports]), + send_reports_for_each_tracking_id(ClientId, TrackingIds, Reports), ok. --spec build_reports_for_each_tracking_id(service_mongoose_system_metrics:client_id(), - [service_mongoose_system_metrics:tracking_id()], - [report_struct()]) -> [google_analytics_report()]. -build_reports_for_each_tracking_id(ClientId, TrackingIds, ReportStructs) -> - lists:map( - fun(Tid) -> - build_reports(ClientId, Tid, ReportStructs) - end, TrackingIds). - --spec build_reports(service_mongoose_system_metrics:client_id(), - service_mongoose_system_metrics:tracking_id(), - [report_struct()]) -> [google_analytics_report()]. -build_reports(ClientId, TrackingId, ReportStructs) -> - lists:map( - fun(Report) -> - build_report(ClientId, TrackingId, Report) - end, ReportStructs). - -send_reports(ReportsList) -> +%-spec build_reports_for_each_tracking_id(service_mongoose_system_metrics:client_id(), +% [service_mongoose_system_metrics:tracking_id()], +% [report_struct()]) -> [google_analytics_report()]. +% +send_reports_for_each_tracking_id(ClientId, TrackingIds, Reports) -> Url = get_url(), lists:map( - fun(Reports) -> - flush_reports(Url, Reports) - end, ReportsList). + fun(TrackingId) -> + flush_reports(Url, Reports, ClientId, TrackingId) + end, TrackingIds). get_url() -> mongoose_config:get_opt(google_analytics_url, ?BASE_URL). % % https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#batch-limitations % % A maximum of 20 hits can be specified per request. --spec flush_reports(url(), [google_analytics_report()]) -> {ok, term()} | {error, term()}. -flush_reports(_, []) -> +flush_reports(_, [], _, _) -> {ok, nothing_to_do}; -flush_reports(ReportUrl, Lines) when length(Lines) =< 20 -> +flush_reports(ReportUrl, Reports, ClientId, + #{id := TrackingId, secret := TrackingSecret}) when length(Reports) =< 20 -> Headers = [], - ContentType = "", - Body = string:join(Lines, "\n"), - Request = {ReportUrl, Headers, ContentType, Body}, - httpc:request(post, Request, [{ssl, [{verify, verify_none}]}], []); -flush_reports(ReportUrl, Lines) -> - {NewBatch, RemainingLines} = lists:split(20, Lines), - flush_reports(ReportUrl, NewBatch), - flush_reports(ReportUrl, RemainingLines). - -build_report(ClientId, TrackingId, #{report_name := EventCategory, key := EventAction, value := EventLabel}) -> - LstClientId = term_to_string(ClientId), - LstEventCategory = term_to_string(EventCategory), - LstEventAction = term_to_string(EventAction), - LstEventLabel = term_to_string(EventLabel), - LstLine = [ - "v=1", - "&tid=", TrackingId, - "&t=event", - "&cid=", LstClientId, - "&ec=", LstEventCategory, - "&ea=", LstEventAction, - "&el=", LstEventLabel], - string:join(LstLine, ""). + ContentType = "application/json", + Body = jiffy:encode(#{client_id => list_to_binary(ClientId), events => Reports}), + io:format("Body: ~p", [Body]), + ReportUrl2 = uri_string:normalize(ReportUrl ++ "?api_secret=" ++ TrackingSecret ++ "&measurement_id=" ++ TrackingId), + io:format("URL: ~p", [ReportUrl2]), + Request = {ReportUrl2, Headers, ContentType, Body}, + Res = httpc:request(post, Request, [{ssl, [{verify, verify_none}]}], []), + io:format("RES: ~p", [Res]), + Res; +flush_reports(ReportUrl, Reports, ClientId, TrackingId) -> + {NewBatch, RemainingLines} = lists:split(20, Reports), + flush_reports(ReportUrl, NewBatch, ClientId, TrackingId), + flush_reports(ReportUrl, RemainingLines, ClientId, TrackingId). term_to_string(Term) when is_binary(Term) -> term_to_string(binary_to_list(Term)); diff --git a/src/system_metrics/service_mongoose_system_metrics.erl b/src/system_metrics/service_mongoose_system_metrics.erl index bb18f77bee6..d823a3646e2 100644 --- a/src/system_metrics/service_mongoose_system_metrics.erl +++ b/src/system_metrics/service_mongoose_system_metrics.erl @@ -7,11 +7,14 @@ -include("mongoose_config_spec.hrl"). -ifdef(PROD_NODE). --define(TRACKING_ID, "UA-151671255-3"). +-define(TRACKING_ID, #{id => "UA-151671255-3", + secret => "8P4wQIkwSV6zay22uKsnLg"}). -else. --define(TRACKING_ID, "UA-151671255-2"). +-define(TRACKING_ID, #{id => "G-7KQE4W9SVJ", + secret => "8P4wQIkwSV6zay22uKsnLg"}). -endif. --define(TRACKING_ID_CI, "UA-151671255-1"). +-define(TRACKING_ID_CI, #{id => "UA-151671255-1", + secret => "8P4wQIkwSV6zay22uKsnLg"}). -include("mongoose.hrl"). @@ -74,7 +77,7 @@ config_spec() -> validate = non_empty} }, defaults = #{<<"initial_report">> => timer:minutes(5), - <<"periodic_report">> => timer:hours(3)} + <<"periodic_report">> => timer:minutes(6)} }. -spec start_link(mongoose_service:options()) -> {ok, pid()}. From 111acadff9ab598465e66ff5967edf13c9e901eb Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Wed, 19 Apr 2023 11:47:47 +0200 Subject: [PATCH 2/6] Changing format of some events --- .../mongoose_system_metrics_collector.erl | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/system_metrics/mongoose_system_metrics_collector.erl b/src/system_metrics/mongoose_system_metrics_collector.erl index c22d7de9a00..9a729286281 100644 --- a/src/system_metrics/mongoose_system_metrics_collector.erl +++ b/src/system_metrics/mongoose_system_metrics_collector.erl @@ -29,17 +29,26 @@ report_getters() -> fun get_domains_count/0, fun get_modules/0, fun get_number_of_custom_modules/0, - fun get_uptime/0, - fun get_cluster_size/0, - fun get_version/0, - fun get_components/0, + fun get_cluster_data/0, fun get_api/0, fun get_transport_mechanisms/0, fun get_tls_options/0, - fun get_outgoing_pools/0, - fun get_config_type/0 + fun get_outgoing_pools/0 ]. +get_cluster_data() -> + Steps = [ + fun get_uptime/0, + fun get_version/0, + fun get_components/0, + fun get_cluster_size/0, + fun get_config_type/0 + ], + Params = lists:foldl(fun(Step, Acc) -> + maps:merge(Acc, Step()) + end, #{}, Steps), + [#{name => cluster, params => Params}]. + get_hosts_count() -> HostTypes = ?ALL_HOST_TYPES, NumberOfHosts = length(HostTypes), @@ -99,23 +108,23 @@ get_number_of_custom_modules() -> mongoose_module_metrics), MetricsModuleSet = sets:from_list(MetricsModule), CountCustomMods= sets:size(sets:subtract(GenModsSet, MetricsModuleSet)), - #{name => custom_modules_count, params => #{value => CountCustomMods}}. + [#{name => custom_modules_count, params => #{value => CountCustomMods}}]. get_uptime() -> {Uptime, _} = statistics(wall_clock), UptimeSeconds = Uptime div 1000, {D, {H, M, S}} = calendar:seconds_to_daystime(UptimeSeconds), Formatted = io_lib:format("~4..0B-~2..0B:~2..0B:~2..0B", [D,H,M,S]), - [#{name => cluster_uptime, params => #{value => list_to_binary(Formatted)}}]. + #{uptime => list_to_binary(Formatted)}. get_cluster_size() -> NodesNo = length(nodes()) + 1, - [#{name => cluster_size, params => #{value => NodesNo}}]. + #{number_of_nodes => NodesNo}. get_version() -> case lists:keyfind(mongooseim, 1, application:which_applications()) of {_, _, Version} -> - #{name => mongooseim_version, params => #{value => list_to_binary(Version)}}; + #{version => list_to_binary(Version)}; _ -> [] end. @@ -124,7 +133,7 @@ get_components() -> Domains = mongoose_router:get_all_domains() ++ ejabberd_router:dirty_get_all_components(all), Components = [ejabberd_router:lookup_component(D, node()) || D <- Domains], LenComponents = length(lists:flatten(Components)), - #{name => cluster_components, params => #{value => LenComponents}}. + #{components => LenComponents}. get_api() -> ApiList = filter_unknown_api(get_http_handler_modules()), @@ -159,10 +168,9 @@ get_http_handler_modules(#{handlers := Handlers}) -> get_tls_options() -> TLSOptions = lists:flatmap(fun extract_tls_options/1, get_listeners(mongoose_c2s_listener)), - [#{name => tls_options, - params => lists:foldl(fun({Key, Val}, Acc) -> - maps:put(Key, Val, Acc) - end, #{}, lists:usort(TLSOptions))}]. + lists:foldl(fun({Mode, Module}, Acc) -> + [#{name => tls_options, params => #{mode => Mode, module => Module}}] ++ Acc + end, [], lists:usort(TLSOptions)). extract_tls_options(#{tls := #{mode := TLSMode, module := TLSModule}}) -> [{TLSMode, TLSModule}]; @@ -171,7 +179,7 @@ extract_tls_options(_) -> []. get_outgoing_pools() -> OutgoingPools = mongoose_config:get_opt(outgoing_pools), [#{name => outgoing_pools, - params => #{key => Type}} || #{type := Type} <- OutgoingPools]. + params => #{value => Type}} || #{type := Type} <- OutgoingPools]. get_xmpp_stanzas_count(PrevReport) -> io:format("PREV_REPORT: ~p", [PrevReport]), @@ -179,7 +187,7 @@ get_xmpp_stanzas_count(PrevReport) -> xmppIqReceived, xmppPresenceSent, xmppPresenceReceived], NewCount = [count_stanzas(StanzaType) || StanzaType <- StanzaTypes], StanzasCount = calculate_stanza_rate(PrevReport, NewCount), - [#{name => xmpp_stanzas_count, + [#{name => xmpp_stanza_count, params => #{ stanza_type => StanzaType, total => Total, @@ -212,4 +220,4 @@ get_config_type() -> ".cfg" -> cfg; _ -> unknown_config_type end, - [#{name => config_type, params => #{config_type => ConfigType}}]. + #{config_type => ConfigType}. From e595fca4447a2690aa391a37b9a39760bce9dc3c Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Tue, 25 Apr 2023 15:47:02 +0200 Subject: [PATCH 3/6] Fixing tests --- .../service_mongoose_system_metrics_SUITE.erl | 146 +++++++++--------- .../mongoose_system_metrics_collector.erl | 4 +- .../mongoose_system_metrics_sender.erl | 16 +- .../service_mongoose_system_metrics.erl | 15 +- 4 files changed, 92 insertions(+), 89 deletions(-) diff --git a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl index a47101ef8b8..7226f469b2d 100644 --- a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl +++ b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl @@ -7,17 +7,16 @@ -define(SERVER_URL, "http://localhost:8765"). -define(ETS_TABLE, qs). --define(TRACKING_ID, "UA-151671255-2"). --define(TRACKING_ID_CI, "UA-151671255-1"). --define(TRACKING_ID_EXTRA, "UA-EXTRA-TRACKING-ID"). +-define(TRACKING_ID, #{id => "G-7KQE4W9SVJ", secret => "Secret"}). +-define(TRACKING_ID_CI, #{id => "G-7KQE4W9SVJ", secret => "Secret2"}). +-define(TRACKING_ID_EXTRA, #{id => "UA-EXTRA-TRACKING-ID", secret => "Secret3"}). -record(event, { - cid = "", - tid = "", - ec = "", - ea = "", - ev = "", - el = "" }). + name = <<"">>, + params = #{}, + client_id = <<"">>, + instance_id = <<"">>, + app_secret = <<"">>}). -import(distributed_helper, [mim/0, mim2/0, mim3/0, rpc/4, require_rpc_nodes/1 @@ -228,7 +227,7 @@ module_opts_are_reported(_Config) -> check_module_backend(mod_privacy, Backend), check_module_backend(mod_private, Backend), check_module_backend(mod_pubsub, Backend), - check_module_opt(mod_push_service_mongoosepush, api_version, <<"\"v3\"">>), + check_module_opt(<<"mod_push_service_mongoosepush">>, <<"api_version">>, <<"\"v3\"">>), check_module_backend(mod_roster, Backend), check_module_backend(mod_vcard, Backend). @@ -239,7 +238,7 @@ rdbms_module_opts_are_reported(_Config) -> check_module_backend(mod_mam, rdbms). check_module_backend(Module, Backend) -> - check_module_opt(Module, backend, atom_to_binary(Backend)). + check_module_opt(atom_to_binary(Module), <<"backend">>, atom_to_binary(Backend)). mongoose_version_is_reported(_Config) -> mongoose_helper:wait_until(fun is_mongoose_version_reported/0, true). @@ -272,7 +271,7 @@ xmpp_stanzas_counts_are_reported(Config) -> escalus:send(Alice, escalus_stanza:chat_to(Bob, <<"Hi">>)), escalus:assert(is_chat_message, [<<"Hi">>], escalus:wait_for_stanza(Bob)), F = fun() -> assert_message_count_is_incremented(Sent, Received) end, - mongoose_helper:wait_until(F, ok) + mongoose_helper:wait_until(F, ok, #{sleep_time => 500, time_left => timer:seconds(20)}) end). config_type_is_reported(_Config) -> @@ -384,31 +383,32 @@ supports_dynamic_domains(Module) -> all_event_have_the_same_client_id() -> Tab = ets:tab2list(?ETS_TABLE), - UniqueSortedTab = lists:usort([Cid || #event{cid = Cid} <- Tab]), + UniqueSortedTab = lists:usort([Cid || #event{client_id = Cid} <- Tab]), 1 = length(UniqueSortedTab). is_host_count_reported() -> - is_in_table(<<"hosts">>). + is_in_table(<<"hosts_count">>). are_modules_reported() -> is_in_table(<<"module">>). -is_in_table(EventCategory) -> +is_in_table(EventName) -> Tab = ets:tab2list(?ETS_TABLE), lists:any( - fun(#event{ec = EC}) -> - verify_category(EC, EventCategory) + fun(#event{name = Name, params = Params}) -> + verify_name(Name, EventName, Params) end, Tab). -verify_category(EC, <<"module">>) -> - Result = re:run(EC, "^mod_.*"), +verify_name(<<"module_with_opts">>, <<"module">>, Params) -> + Module = maps:get(<<"module">>, Params), + Result = re:run(Module, "^mod_.*"), case Result of {match, _Captured} -> true; nomatch -> false end; -verify_category(EC, EC) -> +verify_name(Name, Name, _) -> true; -verify_category(_EC, _EventCategory) -> +verify_name(_, _, _) -> false. get_events_collection_size() -> @@ -464,30 +464,30 @@ primary_tracking_id() -> events_are_reported_to_tracking_ids(ConfiguredTrackingIds) -> Tab = ets:tab2list(?ETS_TABLE), - ActualTrackingIds = lists:usort([Tid || #event{tid = Tid} <- Tab]), - ExpectedTrackingIds = lists:sort([list_to_binary(Tid) || Tid <- ConfiguredTrackingIds]), + ActualTrackingIds = lists:usort([InstanceId || #event{instance_id = InstanceId} <- Tab]), + ExpectedTrackingIds = lists:sort([list_to_binary(Tid) || #{id := Tid} <- ConfiguredTrackingIds]), ?assertEqual(ExpectedTrackingIds, ActualTrackingIds). -is_feature_reported(EventCategory, EventAction) -> - length(match_events(EventCategory, EventAction)) > 0. +is_feature_reported(EventName, Key) -> + length(match_events(EventName, Key)) > 0. -is_feature_reported(EventCategory, EventAction, EventLabel) -> - length(match_events(EventCategory, EventAction, EventLabel)) > 0. +is_feature_reported(EventName, Key, Value) -> + length(match_events(EventName, Key, Value)) > 0. is_module_backend_reported(Module, Backend) -> - is_feature_reported(atom_to_binary(Module), <<"backend">>, atom_to_binary(Backend)). + is_module_opt_reported(Module, <<"backend">>, Backend). is_module_opt_reported(Module, Key, Value) -> - is_feature_reported(atom_to_binary(Module), atom_to_binary(Key), Value). + length(get_matched_events_for_module(Module, Key, Value)) > 0. is_mongoose_version_reported() -> - is_feature_reported(<<"cluster">>, <<"mim_version">>). + is_feature_reported(<<"cluster">>, <<"version">>). is_cluster_uptime_reported() -> is_feature_reported(<<"cluster">>, <<"uptime">>). are_xmpp_components_reported() -> - is_feature_reported(<<"cluster">>, <<"number_of_components">>). + is_feature_reported(<<"cluster">>, <<"components">>). is_config_type_reported() -> IsToml = is_feature_reported(<<"cluster">>, <<"config_type">>, <<"toml">>), @@ -504,68 +504,74 @@ are_outgoing_pools_reported() -> is_in_table(<<"outgoing_pools">>). is_iq_count_reported() -> - is_in_table(<<"xmppIqSent">>). + is_feature_reported(<<"xmpp_stanza_count">>, + <<"stanza_type">>, + <<"xmppIqSent">>). is_message_count_reported() -> - is_in_table(<<"xmppMessageSent">>) andalso is_in_table(<<"xmppMessageReceived">>). + XmppMessageSent = is_feature_reported(<<"xmpp_stanza_count">>, + <<"stanza_type">>, + <<"xmppMessageSent">>), + XmppMessageReceived = is_feature_reported(<<"xmpp_stanza_count">>, + <<"stanza_type">>, + <<"xmppMessageReceived">>), + XmppMessageSent andalso XmppMessageReceived. assert_message_count_is_incremented(Sent, Received) -> assert_increment(<<"xmppMessageSent">>, Sent), assert_increment(<<"xmppMessageReceived">>, Received). assert_increment(EventCategory, InitialValue) -> - Events = match_events(EventCategory, integer_to_binary(InitialValue + 1), <<$1>>), - ?assertMatch([_], Events). % expect exactly one event with an increment of 1 + Events = match_events(<<"xmpp_stanza_count">>, <<"stanza_type">>, EventCategory), + % expect exactly one event with an increment of 1 + SeekedEvent = [Event || Event = #event{params = + #{<<"total">> := Total, <<"increment">> := 1}} <- Events, Total == InitialValue + 1], + ?assertMatch([_], SeekedEvent). get_metric_value(EventCategory) -> - [#event{ea = Value} | _] = match_events(EventCategory), - binary_to_integer(Value). + [#event{params = #{<<"total">> := Value}} | _] = match_events(<<"xmpp_stanza_count">>, <<"stanza_type">>, EventCategory), + Value. more_than_one_component_is_reported() -> - Events = match_events(<<"cluster">>, <<"number_of_components">>), - lists:any(fun(#event{el = EL}) -> - binary_to_integer(EL) > 0 + Events = match_events(<<"cluster">>), + lists:any(fun(#event{params = Params}) -> + maps:get(<<"components">>, Params) > 0 end, Events). -match_events(EC) -> - ets:match_object(?ETS_TABLE, #event{ec = EC, _ = '_'}). +match_events(EventName) -> + ets:match_object(?ETS_TABLE, #event{name = EventName, _ = '_'}). -match_events(EC, EA) -> - ets:match_object(?ETS_TABLE, #event{ec = EC, ea = EA, _ = '_'}). +match_events(EventName, ParamKey) -> + Res = ets:match_object(?ETS_TABLE, #event{name = EventName, _ = '_'}), + [Event || Event = #event{params = #{ParamKey := _}} <- Res]. -match_events(EC, EA, EL) -> - ets:match_object(?ETS_TABLE, #event{ec = EC, ea = EA, el = EL, _ = '_'}). +match_events(EventName, ParamKey, ParamValue) -> + Res = ets:match_object(?ETS_TABLE, #event{name = EventName, _ = '_'}), + [Event || Event = #event{params = #{ParamKey := Value}} <- Res, Value == ParamValue]. + +get_matched_events_for_module(ParamModule, Key, ParamValue) -> + Res = ets:match_object(?ETS_TABLE, #event{name = <<"module_with_opts">>, _ = '_'}), + [Event || Event = #event{params = #{<<"module">> := Module, Key := Value}} <- Res, + Value == ParamValue, Module == ParamModule]. %%-------------------------------------------------------------------- %% Cowboy handlers %%-------------------------------------------------------------------- handler_init(Req0) -> {ok, Body, Req} = cowboy_req:read_body(Req0), - StrEvents = string:split(Body, "\n", all), + #{measurement_id := InstanceId, api_secret := AppSecret} = cowboy_req:match_qs([measurement_id, api_secret], Req0), + BodyMap = jiffy:decode(Body, [return_maps]), + EventTab = maps:get(<<"events">>, BodyMap), + ClientID = maps:get(<<"client_id">>, BodyMap), lists:map( - fun(StrEvent) -> - Event = str_to_event(StrEvent), + fun(Event) -> + EventRecord = #event{name = maps:get(<<"name">>, Event), + params = maps:get(<<"params">>, Event), + client_id = ClientID, + instance_id = InstanceId, + app_secret = AppSecret}, %% TODO there is a race condition when table is not available - ets:insert(?ETS_TABLE, Event) - end, StrEvents), + ets:insert(?ETS_TABLE, EventRecord) + end, EventTab), Req1 = cowboy_req:reply(200, #{}, <<"">>, Req), {ok, Req1, no_state}. - -str_to_event(Qs) -> - StrParams = string:split(Qs, "&", all), - Params = lists:map( - fun(StrParam) -> - [StrKey, StrVal] = string:split(StrParam, "="), - {binary_to_atom(StrKey, utf8), StrVal} - end, StrParams), - #event{ - cid = get_el(cid, Params), - tid = get_el(tid, Params), - ec = get_el(ec, Params), - ea = get_el(ea, Params), - el = get_el(el, Params), - ev = get_el(ev, Params) - }. - -get_el(Key, Proplist) -> - proplists:get_value(Key, Proplist, undef). diff --git a/src/system_metrics/mongoose_system_metrics_collector.erl b/src/system_metrics/mongoose_system_metrics_collector.erl index 9a729286281..2b571a195ee 100644 --- a/src/system_metrics/mongoose_system_metrics_collector.erl +++ b/src/system_metrics/mongoose_system_metrics_collector.erl @@ -182,7 +182,6 @@ get_outgoing_pools() -> params => #{value => Type}} || #{type := Type} <- OutgoingPools]. get_xmpp_stanzas_count(PrevReport) -> - io:format("PREV_REPORT: ~p", [PrevReport]), StanzaTypes = [xmppMessageSent, xmppMessageReceived, xmppIqSent, xmppIqReceived, xmppPresenceSent, xmppPresenceReceived], NewCount = [count_stanzas(StanzaType) || StanzaType <- StanzaTypes], @@ -204,9 +203,8 @@ calculate_stanza_rate([], NewCount) -> [{Type, Count, Count} || {Type, Count} <- NewCount]; calculate_stanza_rate(PrevReport, NewCount) -> ReportProplist = [{Name, Key} || - #{name := xmpp_stanzas_count, + #{name := xmpp_stanza_count, params := #{stanza_type := Name, total := Key}} <- PrevReport], - io:format("ReportProplist: ~p\n", [ReportProplist]), [{Type, Count, case proplists:get_value(Type, ReportProplist) of undefined -> Count; diff --git a/src/system_metrics/mongoose_system_metrics_sender.erl b/src/system_metrics/mongoose_system_metrics_sender.erl index 6eb97776798..bcd86c4efe9 100644 --- a/src/system_metrics/mongoose_system_metrics_sender.erl +++ b/src/system_metrics/mongoose_system_metrics_sender.erl @@ -12,7 +12,6 @@ [report_struct()], [service_mongoose_system_metrics:tracking_id()]) -> ok. send(ClientId, Reports, TrackingIds) -> - io:format("\nReports: ~p", [Reports]), send_reports_for_each_tracking_id(ClientId, TrackingIds, Reports), ok. @@ -39,20 +38,11 @@ flush_reports(ReportUrl, Reports, ClientId, Headers = [], ContentType = "application/json", Body = jiffy:encode(#{client_id => list_to_binary(ClientId), events => Reports}), - io:format("Body: ~p", [Body]), - ReportUrl2 = uri_string:normalize(ReportUrl ++ "?api_secret=" ++ TrackingSecret ++ "&measurement_id=" ++ TrackingId), - io:format("URL: ~p", [ReportUrl2]), + ReportUrl2 = uri_string:normalize( + ReportUrl ++ "?api_secret=" ++ TrackingSecret ++ "&measurement_id=" ++ TrackingId), Request = {ReportUrl2, Headers, ContentType, Body}, - Res = httpc:request(post, Request, [{ssl, [{verify, verify_none}]}], []), - io:format("RES: ~p", [Res]), - Res; + httpc:request(post, Request, [{ssl, [{verify, verify_none}]}], []); flush_reports(ReportUrl, Reports, ClientId, TrackingId) -> {NewBatch, RemainingLines} = lists:split(20, Reports), flush_reports(ReportUrl, NewBatch, ClientId, TrackingId), flush_reports(ReportUrl, RemainingLines, ClientId, TrackingId). - -term_to_string(Term) when is_binary(Term) -> - term_to_string(binary_to_list(Term)); -term_to_string(Term) -> - R = io_lib:format("~p",[Term]), - lists:flatten(R). diff --git a/src/system_metrics/service_mongoose_system_metrics.erl b/src/system_metrics/service_mongoose_system_metrics.erl index d823a3646e2..d5aa138f3d4 100644 --- a/src/system_metrics/service_mongoose_system_metrics.erl +++ b/src/system_metrics/service_mongoose_system_metrics.erl @@ -41,7 +41,7 @@ -type system_metrics_state() :: #system_metrics_state{}. -type client_id() :: string(). --type tracking_id() :: string(). +-type tracking_id() :: #{id => string(), secret => string()}. -spec verify_if_configured() -> ok | ignore. verify_if_configured() -> @@ -73,13 +73,22 @@ config_spec() -> <<"periodic_report">> => #option{type = integer, validate = non_negative}, <<"report">> => #option{type = boolean}, - <<"tracking_id">> => #option{type = string, - validate = non_empty} + <<"tracking_id">> => tracking_id_section() }, defaults = #{<<"initial_report">> => timer:minutes(5), <<"periodic_report">> => timer:minutes(6)} }. +tracking_id_section() -> + #section{ + items = #{<<"id">> => #option{type = string, + validate = non_empty}, + <<"secret">> => #option{type = string, + validate = non_empty} + }, + required = all + }. + -spec start_link(mongoose_service:options()) -> {ok, pid()}. start_link(Opts) -> gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []). From ee8bd44a6bf65c68a27f6e1297659bddf08530a1 Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Wed, 26 Apr 2023 10:22:28 +0200 Subject: [PATCH 4/6] Fixing small tests --- .../tests/service_mongoose_system_metrics_SUITE.erl | 9 +++------ src/system_metrics/service_mongoose_system_metrics.erl | 6 +++--- test/common/config_parser_helper.erl | 5 ++++- test/config_parser_SUITE.erl | 7 +++++-- test/config_parser_SUITE_data/miscellaneous.toml | 3 ++- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl index 7226f469b2d..ee53b52ed20 100644 --- a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl +++ b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl @@ -227,7 +227,7 @@ module_opts_are_reported(_Config) -> check_module_backend(mod_privacy, Backend), check_module_backend(mod_private, Backend), check_module_backend(mod_pubsub, Backend), - check_module_opt(<<"mod_push_service_mongoosepush">>, <<"api_version">>, <<"\"v3\"">>), + check_module_opt(mod_push_service_mongoosepush, <<"api_version">>, <<"v3">>), check_module_backend(mod_roster, Backend), check_module_backend(mod_vcard, Backend). @@ -238,7 +238,7 @@ rdbms_module_opts_are_reported(_Config) -> check_module_backend(mod_mam, rdbms). check_module_backend(Module, Backend) -> - check_module_opt(atom_to_binary(Module), <<"backend">>, atom_to_binary(Backend)). + check_module_opt(Module, <<"backend">>, atom_to_binary(Backend)). mongoose_version_is_reported(_Config) -> mongoose_helper:wait_until(fun is_mongoose_version_reported/0, true). @@ -367,7 +367,7 @@ required_module(Module, Opts) -> check_module_opt(Module, Key, Value) -> case is_module_supported(Module) of true -> - ?assertEqual(true, is_module_opt_reported(Module, Key, Value)); + ?assertEqual(true, is_module_opt_reported(atom_to_binary(Module), Key, Value)); false -> ct:log("Skipping unsupported module ~p", [Module]) end. @@ -474,9 +474,6 @@ is_feature_reported(EventName, Key) -> is_feature_reported(EventName, Key, Value) -> length(match_events(EventName, Key, Value)) > 0. -is_module_backend_reported(Module, Backend) -> - is_module_opt_reported(Module, <<"backend">>, Backend). - is_module_opt_reported(Module, Key, Value) -> length(get_matched_events_for_module(Module, Key, Value)) > 0. diff --git a/src/system_metrics/service_mongoose_system_metrics.erl b/src/system_metrics/service_mongoose_system_metrics.erl index d5aa138f3d4..b6f59fac777 100644 --- a/src/system_metrics/service_mongoose_system_metrics.erl +++ b/src/system_metrics/service_mongoose_system_metrics.erl @@ -7,13 +7,13 @@ -include("mongoose_config_spec.hrl"). -ifdef(PROD_NODE). --define(TRACKING_ID, #{id => "UA-151671255-3", +-define(TRACKING_ID, #{id => "G-7KQE4W9SVJ", secret => "8P4wQIkwSV6zay22uKsnLg"}). -else. -define(TRACKING_ID, #{id => "G-7KQE4W9SVJ", secret => "8P4wQIkwSV6zay22uKsnLg"}). -endif. --define(TRACKING_ID_CI, #{id => "UA-151671255-1", +-define(TRACKING_ID_CI, #{id => "G-7KQE4W9SVJ", secret => "8P4wQIkwSV6zay22uKsnLg"}). -include("mongoose.hrl"). @@ -76,7 +76,7 @@ config_spec() -> <<"tracking_id">> => tracking_id_section() }, defaults = #{<<"initial_report">> => timer:minutes(5), - <<"periodic_report">> => timer:minutes(6)} + <<"periodic_report">> => timer:hours(3)} }. tracking_id_section() -> diff --git a/test/common/config_parser_helper.erl b/test/common/config_parser_helper.erl index b1211590342..c4fd8888c91 100644 --- a/test/common/config_parser_helper.erl +++ b/test/common/config_parser_helper.erl @@ -85,7 +85,10 @@ options("miscellaneous") -> #{service_mongoose_system_metrics => #{initial_report => 20000, periodic_report => 300000, report => true, - tracking_id => "UA-123456789"}}}, + tracking_id => #{ + id => "UA-12345678", + secret => "Secret" + }}}}, {{s2s, <<"anonymous.localhost">>}, default_s2s()}, {{s2s, <<"localhost">>}, default_s2s()}, {sm_backend, mnesia}, diff --git a/test/config_parser_SUITE.erl b/test/config_parser_SUITE.erl index 013c2dfad96..d35113f5ca8 100644 --- a/test/config_parser_SUITE.erl +++ b/test/config_parser_SUITE.erl @@ -2939,13 +2939,16 @@ service_mongoose_system_metrics(_Config) -> ?cfg(P, default_config(P), T(#{})), ?cfg(P ++ [initial_report], 5000, T(#{<<"initial_report">> => 5000})), ?cfg(P ++ [periodic_report], 5000, T(#{<<"periodic_report">> => 5000})), - ?cfg(P ++ [tracking_id], "UA-123456789", T(#{<<"tracking_id">> => <<"UA-123456789">>})), + ?cfg(P ++ [tracking_id], #{id => "UA-12345678", secret => "Secret"}, + T(#{<<"tracking_id">> => #{<<"id">> => <<"UA-12345678">>, <<"secret">> => <<"Secret">>}})), ?cfg(P ++ [report], true, T(#{<<"report">> => true})), ?err(T(#{<<"initial_report">> => <<"forever">>})), ?err(T(#{<<"periodic_report">> => <<"forever">>})), ?err(T(#{<<"initial_report">> => -1})), ?err(T(#{<<"periodic_report">> => -1})), - ?err(T(#{<<"tracking_id">> => 666})), + ?err(T(#{<<"tracking_id">> => #{<<"id">> => 666}})), + ?err(T(#{<<"tracking_id">> => #{<<"secret">> => 666}})), + ?err(T(#{<<"tracking_id">> => #{<<"secret">> => 666, <<"id">> => 666}})), ?err(T(#{<<"report">> => <<"maybe">>})). %% Helpers for module tests diff --git a/test/config_parser_SUITE_data/miscellaneous.toml b/test/config_parser_SUITE_data/miscellaneous.toml index b4a77890a72..032e515ad1e 100644 --- a/test/config_parser_SUITE_data/miscellaneous.toml +++ b/test/config_parser_SUITE_data/miscellaneous.toml @@ -78,4 +78,5 @@ report = true initial_report = 20_000 periodic_report = 300_000 - tracking_id = "UA-123456789" + tracking_id.id = "UA-12345678" + tracking_id.secret = "Secret" From 2cf016067db277d0d29b15d784cf106d72bd18c7 Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Thu, 27 Apr 2023 16:55:30 +0200 Subject: [PATCH 5/6] Fixing documentation --- doc/configuration/Services.md | 12 +++++++++--- .../System-Metrics-Privacy-Policy.md | 11 ++++++++--- test/common/config_parser_helper.erl | 2 +- test/config_parser_SUITE.erl | 4 ++-- test/config_parser_SUITE_data/miscellaneous.toml | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/doc/configuration/Services.md b/doc/configuration/Services.md index 3511a7ed06a..9bab0aab02a 100644 --- a/doc/configuration/Services.md +++ b/doc/configuration/Services.md @@ -82,13 +82,18 @@ Time delay counted when the service is started after which the first metrics rep Time delay for a periodic update report to be created and sent. -### `services.service_mongoose_system_metrics.tracking_id`: +### `services.service_mongoose_system_metrics.tracking_id.id`: * **Syntax:** string * **Default:** no default. -* **Example:** `tracking_id = "UA-123456789"` +* **Example:** `tracking_id.id = "G-123456789"` Tracking ID to forward the reported metrics so that they can be viewed in the Google Analytics dashboard. +### `services.service_mongoose_system_metrics.tracking_id.secret`: +* **Syntax:** string +* **Default:** no default. +* **Example:** `tracking_id.secret = "Secret"` + Removing the `services.service_mongoose_system_metrics` entry will result in the service not being started. Metrics will not be collected and shared. It will generate a notification that the feature is not being used. @@ -135,7 +140,8 @@ The number of seconds after an event must be deleted from the `domain_events` ta report = true initial_report = 300_000 periodic_report = 108_000_000 - tracking_id = "UA-123456789" + tracking_id.id = "G-123456789" + tracking_id.secret = "Secret" [services.service_domain_db] db_pool = "global" diff --git a/doc/operation-and-maintenance/System-Metrics-Privacy-Policy.md b/doc/operation-and-maintenance/System-Metrics-Privacy-Policy.md index 8904cbe0128..db645463ac6 100644 --- a/doc/operation-and-maintenance/System-Metrics-Privacy-Policy.md +++ b/doc/operation-and-maintenance/System-Metrics-Privacy-Policy.md @@ -60,11 +60,15 @@ Tracking ID is a property identification code that all collected data is associa It is determining the destination where the collected data is sent. To create a new Tracking ID, please follow the steps below: +!!! warning + MongooseIM no longer supports Universal Analytics. To use metrics it is needed to create an instance of Google Analytics 4. + * Go to the `Admin` tab of your user dashboard. * Create a new account with `+ Create Account`. * Add new property with `+ Create Property`. - * Within the new property go to `Tracking Info > Tracking Code`. - * Tracking ID can be found in the top left corner of the section and has following format UA-XXXX-Y. + * Within the new property go to `Data Streams > Add stream > Web`. + * After successful creation, the ID can be found in the top right corner of the section and has the following format G-XXXX and is named `Measurement ID`. +* To create an API secret, in a `Data Stream` view go to `Event > Measurement Protocol API secrets` and use the `Create` button in the top right corner to create a new secret. ### Example configuration New Tracking ID can be added to the list of options @@ -72,7 +76,8 @@ New Tracking ID can be added to the list of options [services.service_mongoose_system_metrics] initial_report = 300_000 periodic_report = 10_800_000 - tracking_id = "UA-XXXX-Y" + tracking_id.id = "G-XXXX" + tracking_id.secret = "Secret" ``` For more details regarding service configuration, please see [Services](../configuration/Services.md) section. diff --git a/test/common/config_parser_helper.erl b/test/common/config_parser_helper.erl index c4fd8888c91..b0de4bd1d76 100644 --- a/test/common/config_parser_helper.erl +++ b/test/common/config_parser_helper.erl @@ -86,7 +86,7 @@ options("miscellaneous") -> periodic_report => 300000, report => true, tracking_id => #{ - id => "UA-12345678", + id => "G-12345678", secret => "Secret" }}}}, {{s2s, <<"anonymous.localhost">>}, default_s2s()}, diff --git a/test/config_parser_SUITE.erl b/test/config_parser_SUITE.erl index d35113f5ca8..d92cd29f7fa 100644 --- a/test/config_parser_SUITE.erl +++ b/test/config_parser_SUITE.erl @@ -2939,8 +2939,8 @@ service_mongoose_system_metrics(_Config) -> ?cfg(P, default_config(P), T(#{})), ?cfg(P ++ [initial_report], 5000, T(#{<<"initial_report">> => 5000})), ?cfg(P ++ [periodic_report], 5000, T(#{<<"periodic_report">> => 5000})), - ?cfg(P ++ [tracking_id], #{id => "UA-12345678", secret => "Secret"}, - T(#{<<"tracking_id">> => #{<<"id">> => <<"UA-12345678">>, <<"secret">> => <<"Secret">>}})), + ?cfg(P ++ [tracking_id], #{id => "G-12345678", secret => "Secret"}, + T(#{<<"tracking_id">> => #{<<"id">> => <<"G-12345678">>, <<"secret">> => <<"Secret">>}})), ?cfg(P ++ [report], true, T(#{<<"report">> => true})), ?err(T(#{<<"initial_report">> => <<"forever">>})), ?err(T(#{<<"periodic_report">> => <<"forever">>})), diff --git a/test/config_parser_SUITE_data/miscellaneous.toml b/test/config_parser_SUITE_data/miscellaneous.toml index 032e515ad1e..b94d35fa089 100644 --- a/test/config_parser_SUITE_data/miscellaneous.toml +++ b/test/config_parser_SUITE_data/miscellaneous.toml @@ -78,5 +78,5 @@ report = true initial_report = 20_000 periodic_report = 300_000 - tracking_id.id = "UA-12345678" + tracking_id.id = "G-12345678" tracking_id.secret = "Secret" From cf2ddecaf47eed15da592eab72cf53d56c1586f8 Mon Sep 17 00:00:00 2001 From: Janusz Jakubiec Date: Thu, 4 May 2023 11:15:52 +0200 Subject: [PATCH 6/6] Fixing cr issues --- .../service_mongoose_system_metrics_SUITE.erl | 26 ++++++++--------- .../mongoose_system_metrics_collector.erl | 29 +++++++++---------- .../mongoose_system_metrics_sender.erl | 19 ++++-------- .../service_mongoose_system_metrics.erl | 2 ++ test/config_parser_SUITE.erl | 4 +-- 5 files changed, 37 insertions(+), 43 deletions(-) diff --git a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl index ee53b52ed20..db603c07405 100644 --- a/big_tests/tests/service_mongoose_system_metrics_SUITE.erl +++ b/big_tests/tests/service_mongoose_system_metrics_SUITE.erl @@ -12,11 +12,11 @@ -define(TRACKING_ID_EXTRA, #{id => "UA-EXTRA-TRACKING-ID", secret => "Secret3"}). -record(event, { - name = <<"">>, + name = <<>>, params = #{}, - client_id = <<"">>, - instance_id = <<"">>, - app_secret = <<"">>}). + client_id = <<>>, + instance_id = <<>>, + app_secret = <<>>}). -import(distributed_helper, [mim/0, mim2/0, mim3/0, rpc/4, require_rpc_nodes/1 @@ -387,7 +387,7 @@ all_event_have_the_same_client_id() -> 1 = length(UniqueSortedTab). is_host_count_reported() -> - is_in_table(<<"hosts_count">>). + is_in_table(<<"host_count">>). are_modules_reported() -> is_in_table(<<"module">>). @@ -399,7 +399,7 @@ is_in_table(EventName) -> verify_name(Name, EventName, Params) end, Tab). -verify_name(<<"module_with_opts">>, <<"module">>, Params) -> +verify_name(<<"module_with_opt">>, <<"module">>, Params) -> Module = maps:get(<<"module">>, Params), Result = re:run(Module, "^mod_.*"), case Result of @@ -484,7 +484,7 @@ is_cluster_uptime_reported() -> is_feature_reported(<<"cluster">>, <<"uptime">>). are_xmpp_components_reported() -> - is_feature_reported(<<"cluster">>, <<"components">>). + is_feature_reported(<<"cluster">>, <<"component">>). is_config_type_reported() -> IsToml = is_feature_reported(<<"cluster">>, <<"config_type">>, <<"toml">>), @@ -498,7 +498,7 @@ are_transport_mechanisms_reported() -> is_in_table(<<"transport_mechanism">>). are_outgoing_pools_reported() -> - is_in_table(<<"outgoing_pools">>). + is_in_table(<<"outgoing_pool">>). is_iq_count_reported() -> is_feature_reported(<<"xmpp_stanza_count">>, @@ -521,8 +521,8 @@ assert_message_count_is_incremented(Sent, Received) -> assert_increment(EventCategory, InitialValue) -> Events = match_events(<<"xmpp_stanza_count">>, <<"stanza_type">>, EventCategory), % expect exactly one event with an increment of 1 - SeekedEvent = [Event || Event = #event{params = - #{<<"total">> := Total, <<"increment">> := 1}} <- Events, Total == InitialValue + 1], + SeekedEvent = [Event || Event = #event{params = #{<<"total">> := Total, <<"increment">> := 1}} + <- Events, Total == InitialValue + 1], ?assertMatch([_], SeekedEvent). get_metric_value(EventCategory) -> @@ -532,7 +532,7 @@ get_metric_value(EventCategory) -> more_than_one_component_is_reported() -> Events = match_events(<<"cluster">>), lists:any(fun(#event{params = Params}) -> - maps:get(<<"components">>, Params) > 0 + maps:get(<<"component">>, Params) > 0 end, Events). match_events(EventName) -> @@ -547,7 +547,7 @@ match_events(EventName, ParamKey, ParamValue) -> [Event || Event = #event{params = #{ParamKey := Value}} <- Res, Value == ParamValue]. get_matched_events_for_module(ParamModule, Key, ParamValue) -> - Res = ets:match_object(?ETS_TABLE, #event{name = <<"module_with_opts">>, _ = '_'}), + Res = ets:match_object(?ETS_TABLE, #event{name = <<"module_with_opt">>, _ = '_'}), [Event || Event = #event{params = #{<<"module">> := Module, Key := Value}} <- Res, Value == ParamValue, Module == ParamModule]. @@ -570,5 +570,5 @@ handler_init(Req0) -> %% TODO there is a race condition when table is not available ets:insert(?ETS_TABLE, EventRecord) end, EventTab), - Req1 = cowboy_req:reply(200, #{}, <<"">>, Req), + Req1 = cowboy_req:reply(200, #{}, <<>>, Req), {ok, Req1, no_state}. diff --git a/src/system_metrics/mongoose_system_metrics_collector.erl b/src/system_metrics/mongoose_system_metrics_collector.erl index 2b571a195ee..e658d7aaea0 100644 --- a/src/system_metrics/mongoose_system_metrics_collector.erl +++ b/src/system_metrics/mongoose_system_metrics_collector.erl @@ -4,9 +4,8 @@ -type report_struct() :: #{ - report_name := term(), - key := term(), - value := term() + name := term(), + params := #{term() := term()} }. -export_type([report_struct/0]). @@ -52,11 +51,11 @@ get_cluster_data() -> get_hosts_count() -> HostTypes = ?ALL_HOST_TYPES, NumberOfHosts = length(HostTypes), - [#{name => hosts_count, params => #{value => NumberOfHosts}}]. + [#{name => host_count, params => #{value => NumberOfHosts}}]. get_domains_count() -> DomainsCount = mongoose_domain_core:domains_count(), - [#{name => domains_count, params => #{value => DomainsCount}}]. + [#{name => domain_count, params => #{value => DomainsCount}}]. get_modules() -> HostTypes = ?ALL_HOST_TYPES, @@ -88,7 +87,7 @@ get_modules_metrics(Host, Modules) -> end, Modules). report_module_with_opts(Module, Opts) -> - #{name => module_with_opts, params => + #{name => module_with_opt, params => lists:foldl( fun ({none, _}, Acc) -> @@ -108,7 +107,7 @@ get_number_of_custom_modules() -> mongoose_module_metrics), MetricsModuleSet = sets:from_list(MetricsModule), CountCustomMods= sets:size(sets:subtract(GenModsSet, MetricsModuleSet)), - [#{name => custom_modules_count, params => #{value => CountCustomMods}}]. + [#{name => custom_module_count, params => #{value => CountCustomMods}}]. get_uptime() -> {Uptime, _} = statistics(wall_clock), @@ -119,7 +118,7 @@ get_uptime() -> get_cluster_size() -> NodesNo = length(nodes()) + 1, - #{number_of_nodes => NodesNo}. + #{node_number => NodesNo}. get_version() -> case lists:keyfind(mongooseim, 1, application:which_applications()) of @@ -133,14 +132,14 @@ get_components() -> Domains = mongoose_router:get_all_domains() ++ ejabberd_router:dirty_get_all_components(all), Components = [ejabberd_router:lookup_component(D, node()) || D <- Domains], LenComponents = length(lists:flatten(Components)), - #{components => LenComponents}. + #{component => LenComponents}. get_api() -> ApiList = filter_unknown_api(get_http_handler_modules()), - [#{name => http_api, params => - lists:foldl(fun(Element, Acc) -> - maps:put(Element, enabled, Acc) - end, #{}, ApiList)}]. + [#{name => http_api, + params => lists:foldl(fun(Element, Acc) -> + maps:put(Element, enabled, Acc) + end, #{}, ApiList)}]. filter_unknown_api(ApiList) -> AllowedToReport = [mongoose_client_api, mongoose_admin_api, mod_bosh, mod_websockets], @@ -169,7 +168,7 @@ get_http_handler_modules(#{handlers := Handlers}) -> get_tls_options() -> TLSOptions = lists:flatmap(fun extract_tls_options/1, get_listeners(mongoose_c2s_listener)), lists:foldl(fun({Mode, Module}, Acc) -> - [#{name => tls_options, params => #{mode => Mode, module => Module}}] ++ Acc + [#{name => tls_option, params => #{mode => Mode, module => Module}}] ++ Acc end, [], lists:usort(TLSOptions)). extract_tls_options(#{tls := #{mode := TLSMode, module := TLSModule}}) -> @@ -178,7 +177,7 @@ extract_tls_options(_) -> []. get_outgoing_pools() -> OutgoingPools = mongoose_config:get_opt(outgoing_pools), - [#{name => outgoing_pools, + [#{name => outgoing_pool, params => #{value => Type}} || #{type := Type} <- OutgoingPools]. get_xmpp_stanzas_count(PrevReport) -> diff --git a/src/system_metrics/mongoose_system_metrics_sender.erl b/src/system_metrics/mongoose_system_metrics_sender.erl index bcd86c4efe9..41f758310b2 100644 --- a/src/system_metrics/mongoose_system_metrics_sender.erl +++ b/src/system_metrics/mongoose_system_metrics_sender.erl @@ -12,29 +12,22 @@ [report_struct()], [service_mongoose_system_metrics:tracking_id()]) -> ok. send(ClientId, Reports, TrackingIds) -> - send_reports_for_each_tracking_id(ClientId, TrackingIds, Reports), - ok. - -%-spec build_reports_for_each_tracking_id(service_mongoose_system_metrics:client_id(), -% [service_mongoose_system_metrics:tracking_id()], -% [report_struct()]) -> [google_analytics_report()]. -% -send_reports_for_each_tracking_id(ClientId, TrackingIds, Reports) -> Url = get_url(), lists:map( fun(TrackingId) -> flush_reports(Url, Reports, ClientId, TrackingId) - end, TrackingIds). + end, TrackingIds), + ok. get_url() -> mongoose_config:get_opt(google_analytics_url, ?BASE_URL). -% % https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#batch-limitations -% % A maximum of 20 hits can be specified per request. +% https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#limitations +% % A maximum of 25 hits can be specified per request. flush_reports(_, [], _, _) -> {ok, nothing_to_do}; flush_reports(ReportUrl, Reports, ClientId, - #{id := TrackingId, secret := TrackingSecret}) when length(Reports) =< 20 -> + #{id := TrackingId, secret := TrackingSecret}) when length(Reports) =< 25 -> Headers = [], ContentType = "application/json", Body = jiffy:encode(#{client_id => list_to_binary(ClientId), events => Reports}), @@ -43,6 +36,6 @@ flush_reports(ReportUrl, Reports, ClientId, Request = {ReportUrl2, Headers, ContentType, Body}, httpc:request(post, Request, [{ssl, [{verify, verify_none}]}], []); flush_reports(ReportUrl, Reports, ClientId, TrackingId) -> - {NewBatch, RemainingLines} = lists:split(20, Reports), + {NewBatch, RemainingLines} = lists:split(25, Reports), flush_reports(ReportUrl, NewBatch, ClientId, TrackingId), flush_reports(ReportUrl, RemainingLines, ClientId, TrackingId). diff --git a/src/system_metrics/service_mongoose_system_metrics.erl b/src/system_metrics/service_mongoose_system_metrics.erl index b6f59fac777..c390ca0664c 100644 --- a/src/system_metrics/service_mongoose_system_metrics.erl +++ b/src/system_metrics/service_mongoose_system_metrics.erl @@ -7,6 +7,8 @@ -include("mongoose_config_spec.hrl"). -ifdef(PROD_NODE). +% The value "Secret" here is an app id from Google Analytics. +% We refer to it as "Secret" because it is named there that way. -define(TRACKING_ID, #{id => "G-7KQE4W9SVJ", secret => "8P4wQIkwSV6zay22uKsnLg"}). -else. diff --git a/test/config_parser_SUITE.erl b/test/config_parser_SUITE.erl index d92cd29f7fa..be5ce8ed65b 100644 --- a/test/config_parser_SUITE.erl +++ b/test/config_parser_SUITE.erl @@ -2946,8 +2946,8 @@ service_mongoose_system_metrics(_Config) -> ?err(T(#{<<"periodic_report">> => <<"forever">>})), ?err(T(#{<<"initial_report">> => -1})), ?err(T(#{<<"periodic_report">> => -1})), - ?err(T(#{<<"tracking_id">> => #{<<"id">> => 666}})), - ?err(T(#{<<"tracking_id">> => #{<<"secret">> => 666}})), + ?err(T(#{<<"tracking_id">> => #{<<"id">> => "G-12345678"}})), + ?err(T(#{<<"tracking_id">> => #{<<"secret">> => "Secret"}})), ?err(T(#{<<"tracking_id">> => #{<<"secret">> => 666, <<"id">> => 666}})), ?err(T(#{<<"report">> => <<"maybe">>})).