From 07341e7aa60fe7c7d4f298136af99276820940e7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 14 Oct 2021 20:44:59 +0200 Subject: Add graphs and retention metrics to admin dashboard (#16829) --- app/controllers/admin/dashboard_controller.rb | 36 ++-------------------- .../api/v1/admin/dimensions_controller.rb | 23 ++++++++++++++ .../api/v1/admin/measures_controller.rb | 22 +++++++++++++ .../api/v1/admin/retention_controller.rb | 22 +++++++++++++ app/controllers/api/v1/admin/trends_controller.rb | 16 ++++++++++ .../api/v1/instances/activity_controller.rb | 27 ++++++++-------- 6 files changed, 98 insertions(+), 48 deletions(-) create mode 100644 app/controllers/api/v1/admin/dimensions_controller.rb create mode 100644 app/controllers/api/v1/admin/measures_controller.rb create mode 100644 app/controllers/api/v1/admin/retention_controller.rb create mode 100644 app/controllers/api/v1/admin/trends_controller.rb (limited to 'app/controllers') diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index c829ed98f..cbfff2707 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,49 +1,17 @@ # frozen_string_literal: true -require 'sidekiq/api' module Admin class DashboardController < BaseController def index @system_checks = Admin::SystemCheck.perform - @users_count = User.count + @time_period = (1.month.ago.to_date...Time.now.utc.to_date) @pending_users_count = User.pending.count - @registrations_week = Redis.current.get("activity:accounts:local:#{current_week}") || 0 - @logins_week = Redis.current.pfcount("activity:logins:#{current_week}") - @interactions_week = Redis.current.get("activity:interactions:#{current_week}") || 0 - @relay_enabled = Relay.enabled.exists? - @single_user_mode = Rails.configuration.x.single_user_mode - @registrations_enabled = Setting.registrations_mode != 'none' - @deletions_enabled = Setting.open_deletion - @invites_enabled = Setting.min_invite_role == 'user' - @search_enabled = Chewy.enabled? - @version = Mastodon::Version.to_s - @database_version = ActiveRecord::Base.connection.execute('SELECT VERSION()').first['version'].match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1] - @redis_version = redis_info['redis_version'] - @reports_count = Report.unresolved.count - @queue_backlog = Sidekiq::Stats.new.enqueued - @recent_users = User.confirmed.recent.includes(:account).limit(8) - @database_size = ActiveRecord::Base.connection.execute('SELECT pg_database_size(current_database())').first['pg_database_size'] - @redis_size = redis_info['used_memory'] - @ldap_enabled = ENV['LDAP_ENABLED'] == 'true' - @cas_enabled = ENV['CAS_ENABLED'] == 'true' - @saml_enabled = ENV['SAML_ENABLED'] == 'true' - @pam_enabled = ENV['PAM_ENABLED'] == 'true' - @hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true' - @trending_hashtags = TrendingTags.get(10, filtered: false) + @pending_reports_count = Report.unresolved.count @pending_tags_count = Tag.pending_review.count - @authorized_fetch = authorized_fetch_mode? - @whitelist_enabled = whitelist_mode? - @profile_directory = Setting.profile_directory - @timeline_preview = Setting.timeline_preview - @trends_enabled = Setting.trends end private - def current_week - @current_week ||= Time.now.utc.to_date.cweek - end - def redis_info @redis_info ||= begin if Redis.current.is_a?(Redis::Namespace) diff --git a/app/controllers/api/v1/admin/dimensions_controller.rb b/app/controllers/api/v1/admin/dimensions_controller.rb new file mode 100644 index 000000000..170596d27 --- /dev/null +++ b/app/controllers/api/v1/admin/dimensions_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class Api::V1::Admin::DimensionsController < Api::BaseController + protect_from_forgery with: :exception + + before_action :require_staff! + before_action :set_dimensions + + def create + render json: @dimensions, each_serializer: REST::Admin::DimensionSerializer + end + + private + + def set_dimensions + @dimensions = Admin::Metrics::Dimension.retrieve( + params[:keys], + params[:start_at], + params[:end_at], + params[:limit] + ) + end +end diff --git a/app/controllers/api/v1/admin/measures_controller.rb b/app/controllers/api/v1/admin/measures_controller.rb new file mode 100644 index 000000000..a3ac6fe85 --- /dev/null +++ b/app/controllers/api/v1/admin/measures_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Api::V1::Admin::MeasuresController < Api::BaseController + protect_from_forgery with: :exception + + before_action :require_staff! + before_action :set_measures + + def create + render json: @measures, each_serializer: REST::Admin::MeasureSerializer + end + + private + + def set_measures + @measures = Admin::Metrics::Measure.retrieve( + params[:keys], + params[:start_at], + params[:end_at] + ) + end +end diff --git a/app/controllers/api/v1/admin/retention_controller.rb b/app/controllers/api/v1/admin/retention_controller.rb new file mode 100644 index 000000000..a8ff64f21 --- /dev/null +++ b/app/controllers/api/v1/admin/retention_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class Api::V1::Admin::RetentionController < Api::BaseController + protect_from_forgery with: :exception + + before_action :require_staff! + before_action :set_cohorts + + def create + render json: @cohorts, each_serializer: REST::Admin::CohortSerializer + end + + private + + def set_cohorts + @cohorts = Admin::Metrics::Retention.new( + params[:start_at], + params[:end_at], + params[:frequency] + ).cohorts + end +end diff --git a/app/controllers/api/v1/admin/trends_controller.rb b/app/controllers/api/v1/admin/trends_controller.rb new file mode 100644 index 000000000..e32ab5d2c --- /dev/null +++ b/app/controllers/api/v1/admin/trends_controller.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class Api::V1::Admin::TrendsController < Api::BaseController + before_action :require_staff! + before_action :set_trends + + def index + render json: @trends, each_serializer: REST::Admin::TagSerializer + end + + private + + def set_trends + @trends = TrendingTags.get(10, filtered: false) + end +end diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb index 4f6b4bcbf..bad61425a 100644 --- a/app/controllers/api/v1/instances/activity_controller.rb +++ b/app/controllers/api/v1/instances/activity_controller.rb @@ -14,22 +14,21 @@ class Api::V1::Instances::ActivityController < Api::BaseController private def activity - weeks = [] - - 12.times do |i| - day = i.weeks.ago.to_date - week_id = day.cweek - week = Date.commercial(day.cwyear, week_id) - - weeks << { - week: week.to_time.to_i.to_s, - statuses: Redis.current.get("activity:statuses:local:#{week_id}") || '0', - logins: Redis.current.pfcount("activity:logins:#{week_id}").to_s, - registrations: Redis.current.get("activity:accounts:local:#{week_id}") || '0', + statuses_tracker = ActivityTracker.new('activity:statuses:local', :basic) + logins_tracker = ActivityTracker.new('activity:logins', :unique) + registrations_tracker = ActivityTracker.new('activity:accounts:local', :basic) + + (0...12).map do |i| + start_of_week = i.weeks.ago + end_of_week = start_of_week + 6.days + + { + week: start_of_week.to_i.to_s, + statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s, + logins: logins_tracker.sum(start_of_week, end_of_week).to_s, + registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s, } end - - weeks end def require_enabled_api! -- cgit