diff --git a/config/metrics/counts_28d/20220222215951_xmau_plan.yml b/config/metrics/counts_28d/20220222215951_xmau_plan.yml index 587f34e90c3df09b79fcd51f36429b42c8f2df8c..c254ad942c2cfdbb725e1c1f8ec4fb2c36e00b52 100644 --- a/config/metrics/counts_28d/20220222215951_xmau_plan.yml +++ b/config/metrics/counts_28d/20220222215951_xmau_plan.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_28d/20220222215952_xmau_project_management.yml b/config/metrics/counts_28d/20220222215952_xmau_project_management.yml index 542f8a131181c626ef1aecafb329f037d6f17677..0dad4fd0979fc4e8c2157d76ed5136c5d1edf894 100644 --- a/config/metrics/counts_28d/20220222215952_xmau_project_management.yml +++ b/config/metrics/counts_28d/20220222215952_xmau_project_management.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_28d/20220222215955_users_work_items.yml b/config/metrics/counts_28d/20220222215955_users_work_items.yml index e7a95c9d3356ac94dc9cbd817ba961feac37a99d..ec07fb25f1182fe644d5b03ee8c508e452aa160a 100644 --- a/config/metrics/counts_28d/20220222215955_users_work_items.yml +++ b/config/metrics/counts_28d/20220222215955_users_work_items.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_28d/20220922042106_users_updating_work_item_iteration_monthly.yml b/config/metrics/counts_28d/20220922042106_users_updating_work_item_iteration_monthly.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c19e4e32619e47b63d103bdadef04e5a746f297 --- /dev/null +++ b/config/metrics/counts_28d/20220922042106_users_updating_work_item_iteration_monthly.yml @@ -0,0 +1,24 @@ +--- +key_path: redis_hll_counters.work_items.users_updating_work_item_iteration_monthly +description: Unique users updating a work item's iteration +product_section: team planning +product_stage: dev +product_group: plan +product_category: project_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98539 +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - users_updating_work_item_iteration +distribution: +- ce +- ee +tier: +- premium +- ultimate diff --git a/config/metrics/counts_7d/20220222215851_xmau_plan.yml b/config/metrics/counts_7d/20220222215851_xmau_plan.yml index 4fb302d67ac3e985c73480ac4c567ef4f4e741c3..77325a205eeb9713d4f522ab87f5fde61c19d674 100644 --- a/config/metrics/counts_7d/20220222215851_xmau_plan.yml +++ b/config/metrics/counts_7d/20220222215851_xmau_plan.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_7d/20220222215852_xmau_project_management.yml b/config/metrics/counts_7d/20220222215852_xmau_project_management.yml index a63adfab8aa9ea87eb0afae8cab28cd9f08eb405..c7e712cf92a55ff87758ea568a35e073bda1e14c 100644 --- a/config/metrics/counts_7d/20220222215852_xmau_project_management.yml +++ b/config/metrics/counts_7d/20220222215852_xmau_project_management.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_7d/20220222215855_users_work_items.yml b/config/metrics/counts_7d/20220222215855_users_work_items.yml index cb3120221921c4803951c03ebc27ba96482eeee5..0985f38c83be0253f15c5b72969dce19559feaaa 100644 --- a/config/metrics/counts_7d/20220222215855_users_work_items.yml +++ b/config/metrics/counts_7d/20220222215855_users_work_items.yml @@ -21,6 +21,7 @@ options: - users_updating_work_item_title - users_updating_work_item_dates - users_updating_work_item_labels + - users_updating_work_item_iteration data_category: optional distribution: - ce diff --git a/config/metrics/counts_7d/20220922042528_users_updating_work_item_iteration_weekly.yml b/config/metrics/counts_7d/20220922042528_users_updating_work_item_iteration_weekly.yml new file mode 100644 index 0000000000000000000000000000000000000000..aad949867cfcda41d575450399f6c28c790552c4 --- /dev/null +++ b/config/metrics/counts_7d/20220922042528_users_updating_work_item_iteration_weekly.yml @@ -0,0 +1,24 @@ +--- +key_path: redis_hll_counters.work_items.users_updating_work_item_iteration_weekly +description: Unique users updating a work item's iteration +product_section: team planning +product_stage: dev +product_group: plan +product_category: project_management +value_type: number +status: active +milestone: "15.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98539 +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - users_updating_work_item_iteration +distribution: +- ce +- ee +tier: +- premium +- ultimate diff --git a/ee/app/services/resource_events/change_iteration_service.rb b/ee/app/services/resource_events/change_iteration_service.rb index 53def1785a53b9d7fcd812cd067b0923e1f9c21f..86fc53720ce87a61d550fd7c3f379d6daf658d3e 100644 --- a/ee/app/services/resource_events/change_iteration_service.rb +++ b/ee/app/services/resource_events/change_iteration_service.rb @@ -7,10 +7,20 @@ class ChangeIterationService < ::ResourceEvents::BaseChangeTimeboxService def initialize(resource, user, old_iteration_id:) super(resource, user) + @resource = resource + @user = user @iteration = resource&.iteration @old_iteration_id = old_iteration_id end + def execute + super + + return unless resource.is_a?(WorkItem) + + Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter.track_work_item_iteration_changed_action(author: user) + end + private def create_event diff --git a/ee/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter.rb b/ee/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter.rb index aedd0e3a828215167104744c3dbce970fcf84c13..46872defa9265aa0f35cb606b4844a6b38b22db9 100644 --- a/ee/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter.rb +++ b/ee/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter.rb @@ -7,11 +7,16 @@ module WorkItemActivityUniqueCounter extend ActiveSupport::Concern WORK_ITEM_WEIGHT_CHANGED = 'users_updating_weight_estimate' + WORK_ITEM_ITERATION_CHANGED = 'users_updating_work_item_iteration' class_methods do def track_work_item_weight_changed_action(author:) track_unique_action(WORK_ITEM_WEIGHT_CHANGED, author) end + + def track_work_item_iteration_changed_action(author:) + track_unique_action(WORK_ITEM_ITERATION_CHANGED, author) + end end end end diff --git a/ee/spec/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb b/ee/spec/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb index affc5ce5581285303f4109af0850651f16401e14..fab3057a9783b79890c6c8b1f6315dcc8a3b34b1 100644 --- a/ee/spec/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb +++ b/ee/spec/lib/ee/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb @@ -12,4 +12,12 @@ it_behaves_like 'work item unique counter' end + + describe '.track_work_item_iteration_changed_action' do + subject(:track_event) { described_class.track_work_item_iteration_changed_action(author: user) } + + let(:event_name) { described_class::WORK_ITEM_ITERATION_CHANGED } + + it_behaves_like 'work item unique counter' + end end diff --git a/ee/spec/services/ee/resource_events/change_iteration_service_spec.rb b/ee/spec/services/ee/resource_events/change_iteration_service_spec.rb index cec3cdabb31b7ee2cba1a73aa6a9beb8f937cdd5..f10db46944bea207e696654d8590a3b4fe45e78a 100644 --- a/ee/spec/services/ee/resource_events/change_iteration_service_spec.rb +++ b/ee/spec/services/ee/resource_events/change_iteration_service_spec.rb @@ -14,4 +14,33 @@ let_it_be(:resource) { create(issuable) } # rubocop:disable Rails/SaveBang end end + + describe 'events tracking' do + let_it_be(:user) { create(:user) } + + subject(:changed_service_instance) { described_class.new(resource, user, old_iteration_id: nil) } + + context 'when the resource is a work item' do + let(:resource) { create(:work_item, iteration: timebox) } + + it 'tracks work item usage data counters' do + expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter) + .to receive(:track_work_item_iteration_changed_action) + .with(author: user) + + changed_service_instance.execute + end + end + + context 'when the resource is not a work item' do + let(:resource) { create(:issue, iteration: timebox) } + + it 'does not track work item usage data counters' do + expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter) + .not_to receive(:track_work_item_iteration_changed_action) + + changed_service_instance.execute + end + end + end end diff --git a/lib/gitlab/usage_data_counters/known_events/work_items.yml b/lib/gitlab/usage_data_counters/known_events/work_items.yml index 94b7a37e67e34b74de2af4a65f1d9b41fedd7773..ee828fc0f72413bf1f0816f619776973598820da 100644 --- a/lib/gitlab/usage_data_counters/known_events/work_items.yml +++ b/lib/gitlab/usage_data_counters/known_events/work_items.yml @@ -19,3 +19,11 @@ redis_slot: users aggregation: weekly feature_flag: track_work_items_activity +- name: users_updating_work_item_iteration + # The event tracks an EE feature. + # It's added here so it can be aggregated into the CE/EE 'OR' aggregate metrics. + # It will report 0 for CE instances and should not be used with 'AND' aggregators. + category: work_items + redis_slot: users + aggregation: weekly + feature_flag: track_work_items_activity diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/work_items_activity_aggregated_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/work_items_activity_aggregated_metric_spec.rb index c13a5ba4d7236cddf88e046ea7979751955a9be2..3e315692d0a2b69e49b267f8d556765b7cfbeb4c 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/work_items_activity_aggregated_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/work_items_activity_aggregated_metric_spec.rb @@ -6,7 +6,7 @@ let(:metric_definition) do { data_source: 'redis_hll', - time_frame: '7d', + time_frame: time_frame, options: { aggregate: { operator: 'OR' @@ -15,6 +15,7 @@ users_creating_work_items users_updating_work_item_title users_updating_work_item_dates + users_updating_work_item_iteration ] } } @@ -24,31 +25,36 @@ freeze_time { example.run } end - describe '#available?' do - it 'returns false without track_work_items_activity feature' do - stub_feature_flags(track_work_items_activity: false) + where(:time_frame) { [['28d'], ['7d']] } - expect(described_class.new(metric_definition).available?).to eq(false) - end + with_them do + describe '#available?' do + it 'returns false without track_work_items_activity feature' do + stub_feature_flags(track_work_items_activity: false) + + expect(described_class.new(metric_definition).available?).to eq(false) + end - it 'returns true with track_work_items_activity feature' do - stub_feature_flags(track_work_items_activity: true) + it 'returns true with track_work_items_activity feature' do + stub_feature_flags(track_work_items_activity: true) - expect(described_class.new(metric_definition).available?).to eq(true) + expect(described_class.new(metric_definition).available?).to eq(true) + end end - end - describe '#value', :clean_gitlab_redis_shared_state do - let(:counter) { Gitlab::UsageDataCounters::HLLRedisCounter } + describe '#value', :clean_gitlab_redis_shared_state do + let(:counter) { Gitlab::UsageDataCounters::HLLRedisCounter } - before do - counter.track_event(:users_creating_work_items, values: 1, time: 1.week.ago) - counter.track_event(:users_updating_work_item_title, values: 1, time: 1.week.ago) - counter.track_event(:users_updating_work_item_dates, values: 2, time: 1.week.ago) - end + before do + counter.track_event(:users_creating_work_items, values: 1, time: 1.week.ago) + counter.track_event(:users_updating_work_item_title, values: 1, time: 1.week.ago) + counter.track_event(:users_updating_work_item_dates, values: 2, time: 1.week.ago) + counter.track_event(:users_updating_work_item_iteration, values: 2, time: 1.week.ago) + end - it 'has correct value' do - expect(described_class.new(metric_definition).value).to eq 2 + it 'has correct value' do + expect(described_class.new(metric_definition).value).to eq 2 + end end end end