Skip to content

Commit

Permalink
Changing events format. Sending them to new GA4 instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
Janusz Jakubiec authored and Janusz Jakubiec committed Apr 17, 2023
1 parent 4df69e2 commit 38c3ed4
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 82 deletions.
66 changes: 41 additions & 25 deletions src/system_metrics/mongoose_system_metrics_collector.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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.
Expand All @@ -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],
Expand All @@ -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),
Expand All @@ -150,27 +159,32 @@ 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}];
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]),
Expand All @@ -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;
Expand All @@ -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}}].
1 change: 0 additions & 1 deletion src/system_metrics/mongoose_system_metrics_file.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ save(Reports) ->
JSON = jiffy:encode(Reports, [pretty]),
file:write_file(location(), JSON),
ok.

80 changes: 28 additions & 52 deletions src/system_metrics/mongoose_system_metrics_sender.erl
Original file line number Diff line number Diff line change
@@ -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]).

Expand All @@ -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));
Expand Down
11 changes: 7 additions & 4 deletions src/system_metrics/service_mongoose_system_metrics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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").

Expand Down Expand Up @@ -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()}.
Expand Down

0 comments on commit 38c3ed4

Please sign in to comment.