diff --git a/config/events/g_project_management_issue_created.yml b/config/events/g_project_management_issue_created.yml new file mode 100644 index 0000000000000000000000000000000000000000..0fe5dd5f82e447f27703b55d460cbfa5ee25b0db --- /dev/null +++ b/config/events/g_project_management_issue_created.yml @@ -0,0 +1,24 @@ +--- +description: An issue has been created +category: InternalEventTracking +action: g_project_management_issue_created +label_description: +property_description: +value_description: +extra_properties: +identifiers: + - namespace + - project + - user +product_section: dev +product_stage: plan +product_group: project_management +milestone: "16.1" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123184 +distributions: + - ce + - ee +tiers: + - free + - premium + - ultimate 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 31f090e0f5163ca5b1aab12414fb2ec9630f0e08..429ca636b2cede0a605bd441e4ca32bfc5effed0 100644 --- a/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb @@ -38,8 +38,7 @@ module IssueActivityUniqueCounter class << self def track_issue_created_action(author:, namespace:) - track_snowplow_action(ISSUE_CREATED, author, namespace) - track_unique_action(ISSUE_CREATED, author) + track_internal_action(ISSUE_CREATED, author, namespace) end def track_issue_title_changed_action(author:, project:) @@ -180,14 +179,7 @@ def track_issue_design_comment_removed_action(author:, project:) private def track_snowplow_action(event_name, author, container) - namespace, project = case container - when Project - [container.namespace, container] - when Namespaces::ProjectNamespace - [container.parent, container.project] - else - [container, nil] - end + namespace, project = get_params_from_container(container) return unless author @@ -208,6 +200,30 @@ def track_unique_action(event_name, author) Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: author.id) end + + def track_internal_action(event_name, author, container) + return unless author + + namespace, project = get_params_from_container(container) + + Gitlab::InternalEvents.track_event( + event_name, + user_id: author.id, + project_id: project&.id, + namespace_id: namespace&.id + ) + end + + def get_params_from_container(container) + case container + when Project + [container.namespace, container] + when Namespaces::ProjectNamespace + [container.parent, container.project] + else + [container, nil] + end + end end end end diff --git a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb index ba83d979cadc199d5a3d51ee8aaaab1ca4792873..50e20e4fbcf4f81b023ee90a07d6f1143ecf17f1 100644 --- a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb @@ -66,7 +66,7 @@ def track_action(params) end context 'for Issue created actions' do - it_behaves_like 'tracked issuable snowplow and service ping events with project' do + it_behaves_like 'tracked issuable internal event with project' do let(:action) { described_class::ISSUE_CREATED } let(:original_params) { { namespace: project.project_namespace.reload } } diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb index 25c57aa00c6e5724f3892e635171d5c3ca6c40e6..53eee62b3866d11a6f7571b99fbf1f9b7e7f6629 100644 --- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb @@ -54,11 +54,6 @@ let(:merge_request) { create(:merge_request) } let(:target_project) { merge_request.target_project } - let(:fake_tracker) { instance_spy(Gitlab::Tracking::Destinations::Snowplow) } - - before do - allow(Gitlab::Tracking).to receive(:tracker).and_return(fake_tracker) - end it_behaves_like 'a tracked merge request unique event' do let(:action) { described_class::MR_USER_CREATE_ACTION } @@ -68,36 +63,10 @@ let(:action) { described_class::MR_CREATE_ACTION } end - it 'logs to Snowplow', :aggregate_failures do - # This logic should be extracted to shared_examples - namespace = target_project.namespace - - expect(Gitlab::Tracking::StandardContext) - .to receive(:new) - .with( - project_id: target_project.id, - user_id: user.id, - namespace_id: namespace.id, - plan_name: namespace.actual_plan_name - ) - .and_call_original - - expect(Gitlab::Tracking::ServicePingContext) - .to receive(:new) - .with(data_source: :redis_hll, event: described_class::MR_USER_CREATE_ACTION) - .and_call_original - - expect(fake_tracker).to receive(:event) - .with( - 'InternalEventTracking', - described_class::MR_USER_CREATE_ACTION, - context: [ - an_instance_of(SnowplowTracker::SelfDescribingJson), - an_instance_of(SnowplowTracker::SelfDescribingJson) - ] - ) - .exactly(:once) - subject + it_behaves_like 'internal event tracking' do + let(:action) { described_class::MR_USER_CREATE_ACTION } + let(:project) { target_project } + let(:namespace) { project.namespace } end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index ee47f90fb406159bda3565dfe9954c55e5f65331..4cd73cd3fe6f1e086cbc771d72a1308e4ce8a0cc 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -338,11 +338,13 @@ create(:issue) end - it_behaves_like 'issue_edit snowplow tracking' do + it_behaves_like 'internal event tracking' do let(:issue) { create(:issue) } let(:project) { issue.project } - let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } let(:user) { issue.author } + let(:action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } + let(:namespace) { project.namespace } + subject(:service_action) { issue } end end diff --git a/spec/models/work_item_spec.rb b/spec/models/work_item_spec.rb index e0ec54fd5ff92a762b06415219bee59cf48d8935..bf43a2032e73680868ac69b8403a2fc76b93f977 100644 --- a/spec/models/work_item_spec.rb +++ b/spec/models/work_item_spec.rb @@ -212,11 +212,13 @@ create(:work_item) end - it_behaves_like 'issue_edit snowplow tracking' do + it_behaves_like 'internal event tracking' do let(:work_item) { create(:work_item) } - let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } + let(:action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CREATED } let(:project) { work_item.project } let(:user) { work_item.author } + let(:namespace) { project.namespace } + subject(:service_action) { work_item } end end diff --git a/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb b/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb new file mode 100644 index 0000000000000000000000000000000000000000..e2a4fb3136189b974a8cfcc7cfc54d8b24275c8b --- /dev/null +++ b/spec/support/shared_examples/controllers/internal_event_tracking_examples.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# Requires a context containing: +# - subject +# - action +# - user +# Optionally, the context can contain: +# - project +# - namespace + +RSpec.shared_examples 'internal event tracking' do + let(:fake_tracker) { instance_spy(Gitlab::Tracking::Destinations::Snowplow) } + let(:namespace) { nil } + let(:proejct) { nil } + + before do + allow(Gitlab::Tracking).to receive(:tracker).and_return(fake_tracker) + + allow(Gitlab::Tracking::StandardContext).to receive(:new).and_call_original + allow(Gitlab::Tracking::ServicePingContext).to receive(:new).and_call_original + end + + it 'logs to Snowplow', :aggregate_failures do + subject + + expect(Gitlab::Tracking::StandardContext) + .to have_received(:new) + .with( + project_id: project&.id, + user_id: user.id, + namespace_id: namespace&.id, + plan_name: namespace&.actual_plan_name + ) + + expect(Gitlab::Tracking::ServicePingContext) + .to have_received(:new) + .with(data_source: :redis_hll, event: action) + + expect(fake_tracker).to have_received(:event) + .with( + 'InternalEventTracking', + action, + context: [ + an_instance_of(SnowplowTracker::SelfDescribingJson), + an_instance_of(SnowplowTracker::SelfDescribingJson) + ] + ) + .exactly(:once) + end +end diff --git a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb index ba00e3e06105f7bf216f4c94e929a5a18a113d5e..3d3b619451d5b22cdb218bb32c1512ae1005d82c 100644 --- a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb +++ b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb @@ -6,7 +6,7 @@ # - category # - action # - namespace -# Optionaly, the context can contain: +# Optionally, the context can contain: # - project # - property # - user diff --git a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb index 169fceced7a85f121fc22a31ca7fefdd5cf0c6a9..9dc185553402a0f7ebc14ffd57421eba7c44917a 100644 --- a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'tracked issuable snowplow and service ping events for given event params' do +RSpec.shared_examples 'tracked issuable events' do before do stub_application_setting(usage_ping_enabled: true) end @@ -21,6 +21,10 @@ def count_unique(date_from: Date.today.beginning_of_week, date_to: 1.week.from_n it 'does not track edit actions if author is not present' do expect(track_action({ author: nil }.merge(track_params))).to be_nil end +end + +RSpec.shared_examples 'tracked issuable snowplow and service ping events for given event params' do + it_behaves_like 'tracked issuable events' it 'emits snowplow event' do track_action({ author: user1 }.merge(track_params)) @@ -29,6 +33,23 @@ def count_unique(date_from: Date.today.beginning_of_week, date_to: 1.week.from_n end end +RSpec.shared_examples 'tracked issuable internal event for given event params' do + it_behaves_like 'tracked issuable events' + + it_behaves_like 'internal event tracking' do + subject(:track_event) { track_action({ author: user1 }.merge(track_params)) } + + let(:user) { user1 } + let(:namespace) { project&.namespace } + end +end + +RSpec.shared_examples 'tracked issuable internal event with project' do + it_behaves_like 'tracked issuable internal event for given event params' do + let(:track_params) { original_params || { project: project } } + end +end + RSpec.shared_examples 'tracked issuable snowplow and service ping events with project' do it_behaves_like 'tracked issuable snowplow and service ping events for given event params' do let(:context) do