diff options
Diffstat (limited to 'lib/gitlab/analytics')
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/records_fetcher.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/analytics/unique_visits.rb | 67 |
3 files changed, 38 insertions, 51 deletions
diff --git a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb index 4d47a17545a..be5d9be3d64 100644 --- a/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb +++ b/lib/gitlab/analytics/cycle_analytics/records_fetcher.rb @@ -13,7 +13,7 @@ module Gitlab MAPPINGS = { Issue => { serializer_class: AnalyticsIssueSerializer, - includes_for_query: { project: [:namespace], author: [] }, + includes_for_query: { project: { namespace: [:route] }, author: [] }, columns_for_select: %I[title iid id created_at author_id project_id] }, MergeRequest => { @@ -41,7 +41,7 @@ module Gitlab project = record.project attributes = record.attributes.merge({ project_path: project.path, - namespace_path: project.namespace.path, + namespace_path: project.namespace.route.path, author: record.author }) serializer.represent(attributes) @@ -82,7 +82,7 @@ module Gitlab q = ordered_and_limited_query .joins(ci_build_join) - .select(build_table[:id], round_duration_to_seconds.as('total_time')) + .select(build_table[:id], *time_columns) results = execute_query(q).to_a @@ -90,12 +90,12 @@ module Gitlab end def ordered_and_limited_query - order_by_end_event(query).limit(MAX_RECORDS) + order_by_end_event(query, columns).limit(MAX_RECORDS) end def records results = ordered_and_limited_query - .select(*columns, round_duration_to_seconds.as('total_time')) + .select(*columns, *time_columns) # using preloader instead of includes to avoid AR generating a large column list ActiveRecord::Associations::Preloader.new.preload( @@ -106,6 +106,14 @@ module Gitlab results end # rubocop: enable CodeReuse/ActiveRecord + + def time_columns + [ + stage.start_event.timestamp_projection.as('start_event_timestamp'), + stage.end_event.timestamp_projection.as('end_event_timestamp'), + round_duration_to_seconds.as('total_time') + ] + end end end end diff --git a/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb b/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb index c9a75b39959..80e426e6e17 100644 --- a/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb +++ b/lib/gitlab/analytics/cycle_analytics/stage_query_helpers.rb @@ -24,13 +24,13 @@ module Gitlab end # rubocop: disable CodeReuse/ActiveRecord - def order_by_end_event(query) + def order_by_end_event(query, extra_columns_to_select = [:id]) ordered_query = query.reorder(stage.end_event.timestamp_projection.desc) # When filtering for more than one label, postgres requires the columns in ORDER BY to be present in the GROUP BY clause if requires_grouping? column_list = [ - ordered_query.arel_table[:id], + *extra_columns_to_select, *stage.end_event.column_list, *stage.start_event.column_list ] diff --git a/lib/gitlab/analytics/unique_visits.rb b/lib/gitlab/analytics/unique_visits.rb index 9dd7d048eec..ad746ebbd42 100644 --- a/lib/gitlab/analytics/unique_visits.rb +++ b/lib/gitlab/analytics/unique_visits.rb @@ -3,57 +3,36 @@ module Gitlab module Analytics class UniqueVisits - TARGET_IDS = Set[ - 'g_analytics_contribution', - 'g_analytics_insights', - 'g_analytics_issues', - 'g_analytics_productivity', - 'g_analytics_valuestream', - 'p_analytics_pipelines', - 'p_analytics_code_reviews', - 'p_analytics_valuestream', - 'p_analytics_insights', - 'p_analytics_issues', - 'p_analytics_repo', - 'u_analytics_todos', - 'i_analytics_cohorts', - 'i_analytics_dev_ops_score' - ].freeze - - KEY_EXPIRY_LENGTH = 28.days - def track_visit(visitor_id, target_id, time = Time.zone.now) - target_key = key(target_id, time) - - Gitlab::Redis::SharedState.with do |redis| - redis.multi do |multi| - multi.pfadd(target_key, visitor_id) - multi.expire(target_key, KEY_EXPIRY_LENGTH) - end - end + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(visitor_id, target_id, time) end - def weekly_unique_visits_for_target(target_id, week_of: 7.days.ago) - Gitlab::Redis::SharedState.with do |redis| - redis.pfcount(key(target_id, week_of)) - end + # Returns number of unique visitors for given targets in given time frame + # + # @param [String, Array[<String>]] targets ids of targets to count visits on. Special case for :any + # @param [ActiveSupport::TimeWithZone] start_date start of time frame + # @param [ActiveSupport::TimeWithZone] end_date end of time frame + # @return [Integer] number of unique visitors + def unique_visits_for(targets:, start_date: 7.days.ago, end_date: start_date + 1.week) + target_ids = if targets == :analytics + self.class.analytics_ids + elsif targets == :compliance + self.class.compliance_ids + else + Array(targets) + end + + Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: target_ids, start_date: start_date, end_date: end_date) end - def weekly_unique_visits_for_any_target(week_of: 7.days.ago) - keys = TARGET_IDS.map { |target_id| key(target_id, week_of) } - - Gitlab::Redis::SharedState.with do |redis| - redis.pfcount(*keys) + class << self + def analytics_ids + Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('analytics') end - end - - private - def key(target_id, time) - raise "Invalid target id #{target_id}" unless TARGET_IDS.include?(target_id.to_s) - - year_week = time.strftime('%G-%V') - "#{target_id}-{#{year_week}}" + def compliance_ids + Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('compliance') + end end end end |