feat: upsert stats counters, daily buckets and ETS tops for admin metrics. Refs EventHub/EventHubBack#42 #43 #44 #45 #46
CI / test (push) Failing after 25m40s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped

This commit is contained in:
2026-07-17 23:10:00 +03:00
parent f2445db66c
commit dd754e28cc
20 changed files with 1885 additions and 408 deletions
+35 -27
View File
@@ -310,17 +310,19 @@ count_subscriptions() ->
-spec count_subscriptions_by_date(From :: calendar:datetime(), To :: calendar:datetime()) ->
[{{pos_integer(), pos_integer(), pos_integer()}, non_neg_integer()}].
count_subscriptions_by_date(From, To) ->
All = mnesia:dirty_match_object(#subscription{_ = '_'}),
Filtered = lists:filter(fun(S) -> S#subscription.created_at >= From andalso
S#subscription.created_at =< To end, All),
Counts = lists:foldl(fun(S, Acc) ->
Day = date_part(S#subscription.created_at),
case lists:keyfind(Day, 1, Acc) of
false -> [{Day, 1} | Acc];
{Day, C} -> lists:keyreplace(Day, 1, Acc, {Day, C+1})
end
end, [], Filtered),
lists:sort(Counts).
core_stats:with_daily(subscriptions_created, From, To, fun() ->
All = mnesia:dirty_match_object(#subscription{_ = '_'}),
Filtered = lists:filter(fun(S) -> S#subscription.created_at >= From andalso
S#subscription.created_at =< To end, All),
Counts = lists:foldl(fun(S, Acc) ->
Day = date_part(S#subscription.created_at),
case lists:keyfind(Day, 1, Acc) of
false -> [{Day, 1} | Acc];
{Day, C} -> lists:keyreplace(Day, 1, Acc, {Day, C+1})
end
end, [], Filtered),
lists:sort(Counts)
end).
date_part({{Y,M,D}, _}) -> {Y,M,D}.
@@ -330,13 +332,15 @@ date_part({{Y,M,D}, _}) -> {Y,M,D}.
%%%-------------------------------------------------------------------
-spec count_subscriptions_by_plan() -> [{atom(), non_neg_integer()}].
count_subscriptions_by_plan() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{plan = Plan}, Acc) ->
case lists:keyfind(Plan, 1, Acc) of
false -> [{Plan, 1} | Acc];
{Plan, C} -> lists:keyreplace(Plan, 1, Acc, {Plan, C+1})
end
end, [], Subs).
core_stats:with_dim(subscription, plan, fun() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{plan = Plan}, Acc) ->
case lists:keyfind(Plan, 1, Acc) of
false -> [{Plan, 1} | Acc];
{Plan, C} -> lists:keyreplace(Plan, 1, Acc, {Plan, C+1})
end
end, [], Subs)
end).
%%%-------------------------------------------------------------------
%%% @doc Подсчёт подписок по статусам.
@@ -344,13 +348,15 @@ count_subscriptions_by_plan() ->
%%%-------------------------------------------------------------------
-spec count_subscriptions_by_status() -> [{atom(), non_neg_integer()}].
count_subscriptions_by_status() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{status = Status}, Acc) ->
case lists:keyfind(Status, 1, Acc) of
false -> [{Status, 1} | Acc];
{Status, C} -> lists:keyreplace(Status, 1, Acc, {Status, C+1})
end
end, [], Subs).
core_stats:with_dim(subscription, status, fun() ->
Subs = mnesia:dirty_match_object(#subscription{_ = '_'}),
lists:foldl(fun(#subscription{status = Status}, Acc) ->
case lists:keyfind(Status, 1, Acc) of
false -> [{Status, 1} | Acc];
{Status, C} -> lists:keyreplace(Status, 1, Acc, {Status, C+1})
end
end, [], Subs)
end).
%%%-------------------------------------------------------------------
%%% @doc Количество пробных подписок (trial_used = false).
@@ -358,8 +364,10 @@ count_subscriptions_by_status() ->
%%%-------------------------------------------------------------------
-spec count_trial_subscriptions() -> non_neg_integer().
count_trial_subscriptions() ->
Match = #subscription{trial_used = false, _ = '_'},
length(mnesia:dirty_match_object(Match)).
core_stats:with_counter(trial_subscriptions, fun() ->
Match = #subscription{trial_used = false, _ = '_'},
length(mnesia:dirty_match_object(Match))
end).
%%%-------------------------------------------------------------------
%%% @doc Платные подписки (trial_used = true), истекающие в течение Days дней.