diff options
Diffstat (limited to 'lib/gitlab/usage_data_counters')
12 files changed, 882 insertions, 265 deletions
diff --git a/lib/gitlab/usage_data_counters/aggregated_metrics/common.yml b/lib/gitlab/usage_data_counters/aggregated_metrics/common.yml index 4966afd534a..4d92202e7fd 100644 --- a/lib/gitlab/usage_data_counters/aggregated_metrics/common.yml +++ b/lib/gitlab/usage_data_counters/aggregated_metrics/common.yml @@ -4,21 +4,28 @@ # - "AND": counts unique elements that were observed triggering all of following events # events: list of events names to aggregate into metric. All events in this list must have the same 'redis_slot' and 'aggregation' attributes # see from lib/gitlab/usage_data_counters/known_events/ for the list of valid events. +# source: defines which datasource will be used to locate events that should be included in aggregated metric. Valid values are: +# - database +# - redis # feature_flag: name of development feature flag that will be checked before metrics aggregation is performed. # Corresponding feature flag should have `default_enabled` attribute set to `false`. # This attribute is OPTIONAL and can be omitted, when `feature_flag` is missing no feature flag will be checked. --- - name: compliance_features_track_unique_visits_union operator: OR + source: redis events: ['g_compliance_audit_events', 'g_compliance_dashboard', 'i_compliance_audit_events', 'a_compliance_audit_events_api', 'i_compliance_credential_inventory'] - name: product_analytics_test_metrics_union operator: OR + source: redis events: ['i_search_total', 'i_search_advanced', 'i_search_paid'] - name: product_analytics_test_metrics_intersection operator: AND + source: redis events: ['i_search_total', 'i_search_advanced', 'i_search_paid'] - name: incident_management_alerts_total_unique_counts operator: OR + source: redis events: [ 'incident_management_alert_status_changed', 'incident_management_alert_assigned', @@ -27,6 +34,7 @@ ] - name: incident_management_incidents_total_unique_counts operator: OR + source: redis events: [ 'incident_management_incident_created', 'incident_management_incident_reopened', @@ -40,3 +48,13 @@ 'incident_management_incident_unrelate', 'incident_management_incident_change_confidential' ] +- name: i_testing_paid_monthly_active_user_total + operator: OR + source: redis + events: [ + 'i_testing_web_performance_widget_total', + 'i_testing_full_code_quality_report_total', + 'i_testing_group_code_coverage_visit_total', + 'i_testing_load_performance_widget_total', + 'i_testing_metrics_report_widget_total' +] diff --git a/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb b/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb index 572ad866895..772a4623280 100644 --- a/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/ci_template_unique_counter.rb @@ -4,7 +4,9 @@ module Gitlab::UsageDataCounters class CiTemplateUniqueCounter REDIS_SLOT = 'ci_templates'.freeze + # NOTE: Events originating from implicit Auto DevOps pipelines get prefixed with `implicit_` TEMPLATE_TO_EVENT = { + '5-Minute-Production-App.gitlab-ci.yml' => '5_min_production_app', 'Auto-DevOps.gitlab-ci.yml' => 'auto_devops', 'AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml' => 'aws_cf_deploy_ec2', 'AWS/Deploy-ECS.gitlab-ci.yml' => 'aws_deploy_ecs', @@ -17,19 +19,21 @@ module Gitlab::UsageDataCounters }.freeze class << self - def track_unique_project_event(project_id:, template:) + def track_unique_project_event(project_id:, template:, config_source:) return if Feature.disabled?(:usage_data_track_ci_templates_unique_projects, default_enabled: :yaml) - if event = unique_project_event(template) + if event = unique_project_event(template, config_source) Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event, values: project_id) end end private - def unique_project_event(template) + def unique_project_event(template, config_source) if name = TEMPLATE_TO_EVENT[template] - "p_#{REDIS_SLOT}_#{name}" + prefix = 'implicit_' if config_source.to_s == 'auto_devops_source' + + "p_#{REDIS_SLOT}_#{prefix}#{name}" end end end diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb index 47361d831b2..68ae239debb 100644 --- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb +++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb @@ -13,15 +13,10 @@ module Gitlab AggregationMismatch = Class.new(EventError) SlotMismatch = Class.new(EventError) CategoryMismatch = Class.new(EventError) - UnknownAggregationOperator = Class.new(EventError) InvalidContext = Class.new(EventError) KNOWN_EVENTS_PATH = File.expand_path('known_events/*.yml', __dir__) ALLOWED_AGGREGATIONS = %i(daily weekly).freeze - UNION_OF_AGGREGATED_METRICS = 'OR' - INTERSECTION_OF_AGGREGATED_METRICS = 'AND' - ALLOWED_METRICS_AGGREGATIONS = [UNION_OF_AGGREGATED_METRICS, INTERSECTION_OF_AGGREGATED_METRICS].freeze - AGGREGATED_METRICS_PATH = File.expand_path('aggregated_metrics/*.yml', __dir__) # Track event on entity_id # Increment a Redis HLL counter for unique event_name and entity_id @@ -90,37 +85,40 @@ module Gitlab events_names = events_for_category(category) event_results = events_names.each_with_object({}) do |event, hash| - hash["#{event}_weekly"] = unique_events(event_names: [event], start_date: 7.days.ago.to_date, end_date: Date.current) - hash["#{event}_monthly"] = unique_events(event_names: [event], start_date: 4.weeks.ago.to_date, end_date: Date.current) + hash["#{event}_weekly"] = unique_events(**weekly_time_range.merge(event_names: [event])) + hash["#{event}_monthly"] = unique_events(**monthly_time_range.merge(event_names: [event])) end if eligible_for_totals?(events_names) - event_results["#{category}_total_unique_counts_weekly"] = unique_events(event_names: events_names, start_date: 7.days.ago.to_date, end_date: Date.current) - event_results["#{category}_total_unique_counts_monthly"] = unique_events(event_names: events_names, start_date: 4.weeks.ago.to_date, end_date: Date.current) + event_results["#{category}_total_unique_counts_weekly"] = unique_events(**weekly_time_range.merge(event_names: events_names)) + event_results["#{category}_total_unique_counts_monthly"] = unique_events(**monthly_time_range.merge(event_names: events_names)) end category_results["#{category}"] = event_results end end - def known_event?(event_name) - event_for(event_name).present? + def weekly_time_range + { start_date: 7.days.ago.to_date, end_date: Date.current } end - def aggregated_metrics_monthly_data - aggregated_metrics_data(4.weeks.ago.to_date) + def monthly_time_range + { start_date: 4.weeks.ago.to_date, end_date: Date.current } end - def aggregated_metrics_weekly_data - aggregated_metrics_data(7.days.ago.to_date) + def known_event?(event_name) + event_for(event_name).present? end def known_events @known_events ||= load_events(KNOWN_EVENTS_PATH) end - def aggregated_metrics - @aggregated_metrics ||= load_events(AGGREGATED_METRICS_PATH) + def calculate_events_union(event_names:, start_date:, end_date:) + count_unique_events(event_names: event_names, start_date: start_date, end_date: end_date) do |events| + raise SlotMismatch, events unless events_in_same_slot?(events) + raise AggregationMismatch, events unless events_same_aggregation?(events) + end end private @@ -131,6 +129,8 @@ module Gitlab event = event_for(event_name) raise UnknownEvent, "Unknown event #{event_name}" unless event.present? + return unless feature_enabled?(event) + Gitlab::Redis::HLL.add(key: redis_key(event, time, context), value: values, expiry: expiry(event)) end @@ -139,93 +139,6 @@ module Gitlab Plan.all_plans end - def aggregated_metrics_data(start_date) - aggregated_metrics.each_with_object({}) do |aggregation, weekly_data| - next if aggregation[:feature_flag] && Feature.disabled?(aggregation[:feature_flag], default_enabled: false, type: :development) - - weekly_data[aggregation[:name]] = calculate_count_for_aggregation(aggregation, start_date: start_date, end_date: Date.current) - end - end - - def calculate_count_for_aggregation(aggregation, start_date:, end_date:) - case aggregation[:operator] - when UNION_OF_AGGREGATED_METRICS - calculate_events_union(event_names: aggregation[:events], start_date: start_date, end_date: end_date) - when INTERSECTION_OF_AGGREGATED_METRICS - calculate_events_intersections(event_names: aggregation[:events], start_date: start_date, end_date: end_date) - else - raise UnknownAggregationOperator, "Events should be aggregated with one of operators #{ALLOWED_METRICS_AGGREGATIONS}" - end - end - - # calculate intersection of 'n' sets based on inclusion exclusion principle https://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle - # this method will be extracted to dedicated module with https://gitlab.com/gitlab-org/gitlab/-/issues/273391 - def calculate_events_intersections(event_names:, start_date:, end_date:, subset_powers_cache: Hash.new({})) - # calculate power of intersection of all given metrics from inclusion exclusion principle - # |A + B + C| = (|A| + |B| + |C|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C|) => - # |A & B & C| = - (|A| + |B| + |C|) + (|A & B| + |A & C| + .. + |C & D|) + |A + B + C| - # |A + B + C + D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - |A & B & C & D| => - # |A & B & C & D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - |A + B + C + D| - - # calculate each components of equation except for the last one |A & B & C & D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - ... - subset_powers_data = subsets_intersection_powers(event_names, start_date, end_date, subset_powers_cache) - - # calculate last component of the equation |A & B & C & D| = .... - |A + B + C + D| - power_of_union_of_all_events = begin - subset_powers_cache[event_names.size][event_names.join('_+_')] ||= \ - calculate_events_union(event_names: event_names, start_date: start_date, end_date: end_date) - end - - # in order to determine if part of equation (|A & B & C|, |A & B & C & D|), that represents the intersection that we need to calculate, - # is positive or negative in particular equation we need to determine if number of subsets is even or odd. Please take a look at two examples below - # |A + B + C| = (|A| + |B| + |C|) - (|A & B| + |A & C| + .. + |C & D|) + |A & B & C| => - # |A & B & C| = - (|A| + |B| + |C|) + (|A & B| + |A & C| + .. + |C & D|) + |A + B + C| - # |A + B + C + D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - |A & B & C & D| => - # |A & B & C & D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - |A + B + C + D| - subset_powers_size_even = subset_powers_data.size.even? - - # sum all components of equation except for the last one |A & B & C & D| = (|A| + |B| + |C| + |D|) - (|A & B| + |A & C| + .. + |C & D|) + (|A & B & C| + |B & C & D|) - ... => - sum_of_all_subset_powers = sum_subset_powers(subset_powers_data, subset_powers_size_even) - - # add last component of the equation |A & B & C & D| = sum_of_all_subset_powers - |A + B + C + D| - sum_of_all_subset_powers + (subset_powers_size_even ? power_of_union_of_all_events : -power_of_union_of_all_events) - end - - def sum_subset_powers(subset_powers_data, subset_powers_size_even) - sum_without_sign = subset_powers_data.to_enum.with_index.sum do |value, index| - (index + 1).odd? ? value : -value - end - - (subset_powers_size_even ? -1 : 1) * sum_without_sign - end - - def subsets_intersection_powers(event_names, start_date, end_date, subset_powers_cache) - subset_sizes = (1..(event_names.size - 1)) - - subset_sizes.map do |subset_size| - if subset_size > 1 - # calculate sum of powers of intersection between each subset (with given size) of metrics: #|A + B + C + D| = ... - (|A & B| + |A & C| + .. + |C & D|) - event_names.combination(subset_size).sum do |events_subset| - subset_powers_cache[subset_size][events_subset.join('_&_')] ||= \ - calculate_events_intersections(event_names: events_subset, start_date: start_date, end_date: end_date, subset_powers_cache: subset_powers_cache) - end - else - # calculate sum of powers of each set (metric) alone #|A + B + C + D| = (|A| + |B| + |C| + |D|) - ... - event_names.sum do |event| - subset_powers_cache[subset_size][event] ||= \ - unique_events(event_names: event, start_date: start_date, end_date: end_date) - end - end - end - end - - def calculate_events_union(event_names:, start_date:, end_date:) - count_unique_events(event_names: event_names, start_date: start_date, end_date: end_date) do |events| - raise SlotMismatch, events unless events_in_same_slot?(events) - raise AggregationMismatch, events unless events_same_aggregation?(events) - end - end - def count_unique_events(event_names:, start_date:, end_date:, context: '') events = events_for(Array(event_names).map(&:to_s)) @@ -237,6 +150,12 @@ module Gitlab redis_usage_data { Gitlab::Redis::HLL.count(keys: keys) } end + def feature_enabled?(event) + return true if event[:feature_flag].blank? + + Feature.enabled?(event[:feature_flag], default_enabled: :yaml) + end + # Allow to add totals for events that are in the same redis slot, category and have the same aggregation level # and if there are more than 1 event def eligible_for_totals?(events_names) @@ -340,12 +259,6 @@ module Gitlab end.flatten end - def validate_aggregation_operator!(operator) - return true if ALLOWED_METRICS_AGGREGATIONS.include?(operator) - - raise UnknownAggregationOperator.new("Events should be aggregated with one of operators #{ALLOWED_METRICS_AGGREGATIONS}") - end - def weekly_redis_keys(events:, start_date:, end_date:, context: '') end_date = end_date.end_of_week - 1.week (start_date.to_date..end_date.to_date).map do |date| diff --git a/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb index f649e7f407d..c2662a74432 100644 --- a/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb @@ -145,7 +145,6 @@ module Gitlab private def track_unique_action(action, author, time) - return unless Feature.enabled?(:track_issue_activity_actions, default_enabled: true) return unless author Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id, time: time) diff --git a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml new file mode 100644 index 00000000000..9c19c9e8b8c --- /dev/null +++ b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml @@ -0,0 +1,91 @@ +# Implicit Auto DevOps pipeline events +- name: p_ci_templates_implicit_auto_devops + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_implicit_auto_devops_build + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_implicit_auto_devops_deploy + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_implicit_security_sast + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_implicit_security_secret_detection + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +# Explicit include:template pipeline events +- name: p_ci_templates_5_min_production_app + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_auto_devops + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_aws_cf_deploy_ec2 + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_aws_deploy_ecs + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_auto_devops_build + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_auto_devops_deploy + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_auto_devops_deploy_latest + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_security_sast + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_security_secret_detection + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects + +- name: p_ci_templates_terraform_base_latest + category: ci_templates + redis_slot: ci_templates + aggregation: weekly + feature_flag: usage_data_track_ci_templates_unique_projects diff --git a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml new file mode 100644 index 00000000000..d657c5487d7 --- /dev/null +++ b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml @@ -0,0 +1,166 @@ +--- +- name: i_code_review_mr_diffs + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_mr_diffs +- name: i_code_review_user_single_file_diffs + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_single_file_diffs +- name: i_code_review_mr_single_file_diffs + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_mr_single_file_diffs +- name: i_code_review_user_toggled_task_item_status + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_toggled_task_item_status +- name: i_code_review_user_create_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_create_mr +- name: i_code_review_user_close_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_close_mr +- name: i_code_review_user_reopen_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_reopen_mr +- name: i_code_review_user_approve_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_approve_mr +- name: i_code_review_user_unapprove_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_unapprove_mr +- name: i_code_review_user_resolve_thread + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_resolve_thread +- name: i_code_review_user_unresolve_thread + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_unresolve_thread +- name: i_code_review_edit_mr_title + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_edit_mr_title +- name: i_code_review_edit_mr_desc + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_edit_mr_desc +- name: i_code_review_user_merge_mr + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_merge_mr +- name: i_code_review_user_create_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_create_mr_comment +- name: i_code_review_user_edit_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_edit_mr_comment +- name: i_code_review_user_remove_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_remove_mr_comment +- name: i_code_review_user_create_review_note + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_create_review_note +- name: i_code_review_user_publish_review + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_publish_review +- name: i_code_review_user_create_multiline_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_create_multiline_mr_comment +- name: i_code_review_user_edit_multiline_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_edit_multiline_mr_comment +- name: i_code_review_user_remove_multiline_mr_comment + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_remove_multiline_mr_comment +- name: i_code_review_user_add_suggestion + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_add_suggestion +- name: i_code_review_user_apply_suggestion + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_apply_suggestion +- name: i_code_review_user_assigned + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_assigned +- name: i_code_review_user_marked_as_draft + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_marked_as_draft +- name: i_code_review_user_unmarked_as_draft + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_unmarked_as_draft +- name: i_code_review_user_review_requested + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_review_requested +- name: i_code_review_user_approval_rule_added + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_approval_rule_added +- name: i_code_review_user_approval_rule_deleted + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_approval_rule_deleted +- name: i_code_review_user_approval_rule_edited + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_approval_rule_edited +- name: i_code_review_user_vs_code_api_request + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_vs_code_api_request +- name: i_code_review_user_create_mr_from_issue + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_create_mr_from_issue diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index 4cbde0c0372..79f319b2d58 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -268,172 +268,154 @@ redis_slot: testing aggregation: weekly feature_flag: usage_data_i_testing_web_performance_widget_total +- name: i_testing_group_code_coverage_project_click_total + category: testing + redis_slot: testing + aggregation: weekly + feature_flag: usage_data_i_testing_group_code_coverage_project_click_total +- name: i_testing_load_performance_widget_total + category: testing + redis_slot: testing + aggregation: weekly + feature_flag: usage_data_i_testing_load_performance_widget_total +- name: i_testing_metrics_report_artifact_uploaders + category: testing + redis_slot: testing + aggregation: weekly + feature_flag: usage_data_i_testing_metrics_report_artifact_uploaders # Project Management group - name: g_project_management_issue_title_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_description_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_assignee_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_made_confidential category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_made_visible category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_created category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_closed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_reopened category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_label_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_milestone_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_iteration_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_weight_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_cross_referenced category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_moved category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_related category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_unrelated category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_marked_as_duplicate category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_locked category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_unlocked category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_added_to_epic category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_removed_from_epic category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_changed_epic category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_designs_added category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_designs_modified category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_designs_removed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_due_date_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_time_estimate_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_time_spent_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_comment_added category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_comment_edited category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_comment_removed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_health_status_changed category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions - name: g_project_management_issue_cloned category: issues_edit redis_slot: project_management aggregation: daily - feature_flag: track_issue_activity_actions # Secrets Management - name: i_ci_secrets_management_vault_build_created category: ci_secrets_management @@ -445,126 +427,15 @@ redis_slot: snippets aggregation: weekly feature_flag: usage_data_i_snippets_show -# Merge request counters -- name: i_code_review_mr_diffs - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_mr_diffs -- name: i_code_review_user_single_file_diffs - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_single_file_diffs -- name: i_code_review_mr_single_file_diffs - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_mr_single_file_diffs -- name: i_code_review_user_create_mr - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_create_mr -- name: i_code_review_user_close_mr - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_close_mr -- name: i_code_review_user_reopen_mr - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_reopen_mr -- name: i_code_review_user_merge_mr - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_merge_mr -- name: i_code_review_user_create_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_create_mr_comment -- name: i_code_review_user_edit_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_edit_mr_comment -- name: i_code_review_user_remove_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_remove_mr_comment -- name: i_code_review_user_create_review_note - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_create_review_note -- name: i_code_review_user_publish_review - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_publish_review -- name: i_code_review_user_create_multiline_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_create_multiline_mr_comment -- name: i_code_review_user_edit_multiline_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_edit_multiline_mr_comment -- name: i_code_review_user_remove_multiline_mr_comment - redis_slot: code_review - category: code_review - aggregation: weekly - feature_flag: usage_data_i_code_review_user_remove_multiline_mr_comment # Terraform - name: p_terraform_state_api_unique_users category: terraform redis_slot: terraform aggregation: weekly feature_flag: usage_data_p_terraform_state_api_unique_users -# CI templates -- name: p_ci_templates_auto_devops - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_aws_cf_deploy_ec2 - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_auto_devops_build - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_auto_devops_deploy - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_auto_devops_deploy_latest - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_security_sast - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_security_secret_detection - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects -- name: p_ci_templates_terraform_base_latest - category: ci_templates - redis_slot: ci_templates - aggregation: weekly - feature_flag: usage_data_track_ci_templates_unique_projects +# Pipeline Authoring +- name: o_pipeline_authoring_unique_users_committing_ciconfigfile + category: pipeline_authoring + redis_slot: pipeline_authoring + aggregation: weekly + feature_flag: usage_data_unique_users_committing_ciconfigfile diff --git a/lib/gitlab/usage_data_counters/known_events/ecosystem.yml b/lib/gitlab/usage_data_counters/known_events/ecosystem.yml new file mode 100644 index 00000000000..3fd02164f74 --- /dev/null +++ b/lib/gitlab/usage_data_counters/known_events/ecosystem.yml @@ -0,0 +1,22 @@ +--- +# Ecosystem category +- name: i_ecosystem_jira_service_close_issue + category: ecosystem + redis_slot: ecosystem + aggregation: weekly + feature_flag: usage_data_track_ecosystem_jira_service +- name: i_ecosystem_jira_service_cross_reference + category: ecosystem + redis_slot: ecosystem + aggregation: weekly + feature_flag: usage_data_track_ecosystem_jira_service +- name: i_ecosystem_jira_service_list_issues + category: ecosystem + redis_slot: ecosystem + aggregation: weekly + feature_flag: usage_data_track_ecosystem_jira_service +- name: i_ecosystem_jira_service_create_issue + category: ecosystem + redis_slot: ecosystem + aggregation: weekly + feature_flag: usage_data_track_ecosystem_jira_service diff --git a/lib/gitlab/usage_data_counters/known_events/quickactions.yml b/lib/gitlab/usage_data_counters/known_events/quickactions.yml new file mode 100644 index 00000000000..bf292047da0 --- /dev/null +++ b/lib/gitlab/usage_data_counters/known_events/quickactions.yml @@ -0,0 +1,326 @@ +--- +- name: i_quickactions_approve + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_assign_single + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_assign_multiple + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_assign_self + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_assign_reviewer + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_award + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_board_move + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_child_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_clear_weight + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_clone + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_close + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_confidential + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_copy_metadata_merge_request + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_copy_metadata_issue + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_create_merge_request + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_done + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_draft + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_due + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_duplicate + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_estimate + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_iteration + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_label + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_lock + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_merge + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_milestone + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_move + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_parent_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_promote + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_publish + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_reassign + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_reassign_reviewer + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_rebase + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_relabel + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_relate + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_child_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_due_date + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_estimate + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_iteration + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_milestone + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_parent_epic + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_time_spent + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_remove_zoom + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_reopen + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_shrug + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_spend_subtract + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_spend_add + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_submit_review + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_subscribe + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_tableflip + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_tag + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_target_branch + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_title + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_todo + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unassign_specific + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unassign_all + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unassign_reviewer + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unlabel_specific + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unlabel_all + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unlock + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_unsubscribe + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_weight + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_wip + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions +- name: i_quickactions_zoom + category: quickactions + redis_slot: quickactions + aggregation: weekly + feature_flag: usage_data_track_quickactions diff --git a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb index 11d59257ed9..b9856e1f74a 100644 --- a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb @@ -10,6 +10,8 @@ module Gitlab MR_CLOSE_ACTION = 'i_code_review_user_close_mr' MR_REOPEN_ACTION = 'i_code_review_user_reopen_mr' MR_MERGE_ACTION = 'i_code_review_user_merge_mr' + MR_APPROVE_ACTION = 'i_code_review_user_approve_mr' + MR_UNAPPROVE_ACTION = 'i_code_review_user_unapprove_mr' MR_CREATE_COMMENT_ACTION = 'i_code_review_user_create_mr_comment' MR_EDIT_COMMENT_ACTION = 'i_code_review_user_edit_mr_comment' MR_REMOVE_COMMENT_ACTION = 'i_code_review_user_remove_mr_comment' @@ -18,6 +20,21 @@ module Gitlab MR_CREATE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_create_multiline_mr_comment' MR_EDIT_MULTILINE_COMMENT_ACTION = 'i_code_review_user_edit_multiline_mr_comment' MR_REMOVE_MULTILINE_COMMENT_ACTION = 'i_code_review_user_remove_multiline_mr_comment' + MR_ADD_SUGGESTION_ACTION = 'i_code_review_user_add_suggestion' + MR_APPLY_SUGGESTION_ACTION = 'i_code_review_user_apply_suggestion' + MR_MARKED_AS_DRAFT_ACTION = 'i_code_review_user_marked_as_draft' + MR_UNMARKED_AS_DRAFT_ACTION = 'i_code_review_user_unmarked_as_draft' + MR_RESOLVE_THREAD_ACTION = 'i_code_review_user_resolve_thread' + MR_UNRESOLVE_THREAD_ACTION = 'i_code_review_user_unresolve_thread' + MR_ASSIGNED_USERS_ACTION = 'i_code_review_user_assigned' + MR_REVIEW_REQUESTED_USERS_ACTION = 'i_code_review_user_review_requested' + MR_TASK_ITEM_STATUS_CHANGED_ACTION = 'i_code_review_user_toggled_task_item_status' + MR_APPROVAL_RULE_ADDED_USERS_ACTION = 'i_code_review_user_approval_rule_added' + MR_APPROVAL_RULE_EDITED_USERS_ACTION = 'i_code_review_user_approval_rule_edited' + MR_APPROVAL_RULE_DELETED_USERS_ACTION = 'i_code_review_user_approval_rule_deleted' + MR_EDIT_MR_TITLE_ACTION = 'i_code_review_edit_mr_title' + MR_EDIT_MR_DESC_ACTION = 'i_code_review_edit_mr_desc' + MR_CREATE_FROM_ISSUE_ACTION = 'i_code_review_user_create_mr_from_issue' class << self def track_mr_diffs_action(merge_request:) @@ -45,6 +62,22 @@ module Gitlab track_unique_action_by_user(MR_REOPEN_ACTION, user) end + def track_approve_mr_action(user:) + track_unique_action_by_user(MR_APPROVE_ACTION, user) + end + + def track_unapprove_mr_action(user:) + track_unique_action_by_user(MR_UNAPPROVE_ACTION, user) + end + + def track_resolve_thread_action(user:) + track_unique_action_by_user(MR_RESOLVE_THREAD_ACTION, user) + end + + def track_unresolve_thread_action(user:) + track_unique_action_by_user(MR_UNRESOLVE_THREAD_ACTION, user) + end + def track_create_comment_action(note:) track_unique_action_by_user(MR_CREATE_COMMENT_ACTION, note.author) track_multiline_unique_action(MR_CREATE_MULTILINE_COMMENT_ACTION, note) @@ -68,6 +101,58 @@ module Gitlab track_unique_action_by_user(MR_PUBLISH_REVIEW_ACTION, user) end + def track_add_suggestion_action(user:) + track_unique_action_by_user(MR_ADD_SUGGESTION_ACTION, user) + end + + def track_marked_as_draft_action(user:) + track_unique_action_by_user(MR_MARKED_AS_DRAFT_ACTION, user) + end + + def track_unmarked_as_draft_action(user:) + track_unique_action_by_user(MR_UNMARKED_AS_DRAFT_ACTION, user) + end + + def track_apply_suggestion_action(user:) + track_unique_action_by_user(MR_APPLY_SUGGESTION_ACTION, user) + end + + def track_users_assigned_to_mr(users:) + track_unique_action_by_users(MR_ASSIGNED_USERS_ACTION, users) + end + + def track_users_review_requested(users:) + track_unique_action_by_users(MR_REVIEW_REQUESTED_USERS_ACTION, users) + end + + def track_title_edit_action(user:) + track_unique_action_by_user(MR_EDIT_MR_TITLE_ACTION, user) + end + + def track_description_edit_action(user:) + track_unique_action_by_user(MR_EDIT_MR_DESC_ACTION, user) + end + + def track_approval_rule_added_action(user:) + track_unique_action_by_user(MR_APPROVAL_RULE_ADDED_USERS_ACTION, user) + end + + def track_approval_rule_edited_action(user:) + track_unique_action_by_user(MR_APPROVAL_RULE_EDITED_USERS_ACTION, user) + end + + def track_approval_rule_deleted_action(user:) + track_unique_action_by_user(MR_APPROVAL_RULE_DELETED_USERS_ACTION, user) + end + + def track_task_item_status_changed(user:) + track_unique_action_by_user(MR_TASK_ITEM_STATUS_CHANGED_ACTION, user) + end + + def track_mr_create_from_issue(user:) + track_unique_action_by_user(MR_CREATE_FROM_ISSUE_ACTION, user) + end + private def track_unique_action_by_merge_request(action, merge_request) @@ -80,6 +165,12 @@ module Gitlab track_unique_action(action, user.id) end + def track_unique_action_by_users(action, users) + return if users.blank? + + track_unique_action(action, users.map(&:id)) + end + def track_unique_action(action, value) Gitlab::UsageDataCounters::HLLRedisCounter.track_usage_event(action, value) end diff --git a/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb new file mode 100644 index 00000000000..f757b51f73c --- /dev/null +++ b/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Gitlab + module UsageDataCounters + module QuickActionActivityUniqueCounter + class << self + # Tracks the quick action with name `name`. + # `args` is expected to be a single string, will be split internally when necessary. + def track_unique_action(name, args:, user:) + return unless Feature.enabled?(:usage_data_track_quickactions, default_enabled: :yaml) + return unless user + + args ||= '' + name = prepare_name(name, args) + + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(:"i_quickactions_#{name}", values: user.id) + end + + private + + def prepare_name(name, args) + case name + when 'assign' + event_name_for_assign(args) + when 'copy_metadata' + event_name_for_copy_metadata(args) + when 'remove_reviewer' + 'unassign_reviewer' + when 'request_review', 'reviewer' + 'assign_reviewer' + when 'spend' + event_name_for_spend(args) + when 'unassign' + event_name_for_unassign(args) + when 'unlabel', 'remove_label' + event_name_for_unlabel(args) + else + name + end + end + + def event_name_for_assign(args) + args = args.split + + if args.count == 1 && args.first == 'me' + 'assign_self' + elsif args.count == 1 + 'assign_single' + else + 'assign_multiple' + end + end + + def event_name_for_copy_metadata(args) + if args.start_with?('#') + 'copy_metadata_issue' + else + 'copy_metadata_merge_request' + end + end + + def event_name_for_spend(args) + if args.start_with?('-') + 'spend_subtract' + else + 'spend_add' + end + end + + def event_name_for_unassign(args) + if args.present? + 'unassign_specific' + else + 'unassign_all' + end + end + + def event_name_for_unlabel(args) + if args.present? + 'unlabel_specific' + else + 'unlabel_all' + end + end + end + end + end +end diff --git a/lib/gitlab/usage_data_counters/vs_code_extension_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/vs_code_extension_activity_unique_counter.rb new file mode 100644 index 00000000000..703c4885b04 --- /dev/null +++ b/lib/gitlab/usage_data_counters/vs_code_extension_activity_unique_counter.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Gitlab + module UsageDataCounters + module VSCodeExtensionActivityUniqueCounter + VS_CODE_API_REQUEST_ACTION = 'i_code_review_user_vs_code_api_request' + VS_CODE_USER_AGENT_REGEX = /\Avs-code-gitlab-workflow/.freeze + + class << self + def track_api_request_when_trackable(user_agent:, user:) + user_agent&.match?(VS_CODE_USER_AGENT_REGEX) && track_unique_action_by_user(VS_CODE_API_REQUEST_ACTION, user) + end + + private + + def track_unique_action_by_user(action, user) + return unless user + + track_unique_action(action, user.id) + end + + def track_unique_action(action, value) + Gitlab::UsageDataCounters::HLLRedisCounter.track_usage_event(action, value) + end + end + end + end +end |