From bc33fb70204759cb646b4568d2cea6dcc17dedc0 Mon Sep 17 00:00:00 2001
From: Niko Belokolodov <nbelokolodov@gitlab.com>
Date: Mon, 15 Aug 2022 01:01:39 +0000
Subject: [PATCH] Migrate issues events to Snowplow

Copy issues_ events to Snowplow along with RedisHLL.
Behind FF
---
 app/services/notes/create_service.rb          |  3 +-
 app/services/notes/destroy_service.rb         |  3 +-
 app/services/notes/update_service.rb          |  3 +-
 .../system_notes/issuables_service.rb         |  4 ++-
 ..._project_management_issue_changed_epic.yml | 20 -----------
 ...management_issue_health_status_changed.yml | 20 -----------
 ...ect_management_issue_iteration_changed.yml | 20 -----------
 ...ect_management_issue_removed_from_epic.yml | 20 -----------
 ...roject_management_issue_weight_changed.yml | 20 -----------
 ..._issue_actions_perform_issue_acitons_.yml} | 17 ++++++----
 ee/app/services/ee/issues/base_service.rb     |  6 ++--
 ee/app/services/ee/issues/move_service.rb     |  3 +-
 .../resource_events/change_weight_service.rb  |  3 +-
 .../issue_activity_unique_counter_spec.rb     | 17 ++++++----
 .../models/resource_iteration_event_spec.rb   | 11 +++---
 .../services/ee/issues/clone_service_spec.rb  | 11 +++---
 .../services/ee/issues/move_service_spec.rb   | 12 +++----
 .../services/ee/issues/update_service_spec.rb | 26 +++++---------
 .../ee/system_notes/issuables_service_spec.rb |  7 ++--
 .../change_weight_service_spec.rb             |  7 ++--
 .../services/issue_epic_shared_examples.rb    | 18 ++++------
 .../issue_activity_unique_counter.rb          | 34 ++++++++++++-------
 .../issue_activity_unique_counter_spec.rb     | 21 +++++++-----
 spec/services/notes/create_service_spec.rb    | 33 ++++++++++++------
 spec/services/notes/destroy_service_spec.rb   | 26 +++++++++-----
 spec/services/notes/update_service_spec.rb    | 34 ++++++++++++-------
 .../system_notes/issuables_service_spec.rb    |  9 +++--
 .../issuable_activity_shared_examples.rb      |  8 ++---
 .../snowplow_tracking_shared_examples.rb      | 11 ++++++
 29 files changed, 187 insertions(+), 240 deletions(-)
 delete mode 100644 config/events/1656555050_issues_edit_g_project_management_issue_changed_epic.yml
 delete mode 100644 config/events/1656555163_issues_edit_g_project_management_issue_health_status_changed.yml
 delete mode 100644 config/events/1656555272_issues_edit_g_project_management_issue_iteration_changed.yml
 delete mode 100644 config/events/1656555342_issues_edit_g_project_management_issue_removed_from_epic.yml
 delete mode 100644 config/events/1656555426_issues_edit_g_project_management_issue_weight_changed.yml
 rename config/events/{1656554755_issues_edit_g_project_management_issue_added_to_epic.yml => 1659067369_issue_actions_perform_issue_acitons_.yml} (57%)
 create mode 100644 spec/support/shared_examples/services/snowplow_tracking_shared_examples.rb

diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 90edeacf6336a..b7e6a50fa5c88 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -147,7 +147,8 @@ def tracking_data_for(note)
     end
 
     def track_note_creation_usage_for_issues(note)
-      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_added_action(author: note.author)
+      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_added_action(author: note.author,
+                                                                                             project: project)
     end
 
     def track_note_creation_usage_for_merge_requests(note)
diff --git a/app/services/notes/destroy_service.rb b/app/services/notes/destroy_service.rb
index c25b1ab037932..eda8bbcbc2e41 100644
--- a/app/services/notes/destroy_service.rb
+++ b/app/services/notes/destroy_service.rb
@@ -15,7 +15,8 @@ def execute(note)
     private
 
     def track_note_removal_usage_for_issues(note)
-      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_removed_action(author: note.author)
+      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_removed_action(author: note.author,
+                                                                                               project: project)
     end
 
     def track_note_removal_usage_for_merge_requests(note)
diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb
index 04fc4c7c94451..2dae76feb0b38 100644
--- a/app/services/notes/update_service.rb
+++ b/app/services/notes/update_service.rb
@@ -86,7 +86,8 @@ def update_todos(note, old_mentioned_users)
     end
 
     def track_note_edit_usage_for_issues(note)
-      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_edited_action(author: note.author)
+      Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_edited_action(author: note.author,
+                                                                                              project: project)
     end
 
     def track_note_edit_usage_for_merge_requests(note)
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb
index d2c6e9890db74..1c724df44da0c 100644
--- a/app/services/system_notes/issuables_service.rb
+++ b/app/services/system_notes/issuables_service.rb
@@ -327,7 +327,9 @@ def noteable_cloned(noteable_ref, direction, created_at: nil)
       cross_reference = noteable_ref.to_reference(project)
       body = "cloned #{direction} #{cross_reference}"
 
-      issue_activity_counter.track_issue_cloned_action(author: author) if noteable.is_a?(Issue) && direction == :to
+      if noteable.is_a?(Issue) && direction == :to
+        issue_activity_counter.track_issue_cloned_action(author: author, project: project)
+      end
 
       create_note(NoteSummary.new(noteable, project, author, body, action: 'cloned', created_at: created_at))
     end
diff --git a/config/events/1656555050_issues_edit_g_project_management_issue_changed_epic.yml b/config/events/1656555050_issues_edit_g_project_management_issue_changed_epic.yml
deleted file mode 100644
index b74054b4eb5e9..0000000000000
--- a/config/events/1656555050_issues_edit_g_project_management_issue_changed_epic.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-description: Epic was changed on an issue
-category: issues_edit
-action: g_project_management_issue_changed_epic
-identifiers:
-  - project
-  - user
-  - namespace
-product_section: dev
-product_stage: plan
-product_group: project_management
-product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
-distributions:
-  - ee
-tiers:
-  - premium
-  - ultimate
-
diff --git a/config/events/1656555163_issues_edit_g_project_management_issue_health_status_changed.yml b/config/events/1656555163_issues_edit_g_project_management_issue_health_status_changed.yml
deleted file mode 100644
index 00a375074f6a5..0000000000000
--- a/config/events/1656555163_issues_edit_g_project_management_issue_health_status_changed.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-description: Health status was changed on an issue
-category: issues_edit
-action: g_project_management_issue_health_status_changed
-identifiers:
-  - project
-  - user
-  - namespace
-product_section: dev
-product_stage: plan
-product_group: project_management
-product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
-distributions:
-  - ee
-tiers:
-  - premium
-  - ultimate
-
diff --git a/config/events/1656555272_issues_edit_g_project_management_issue_iteration_changed.yml b/config/events/1656555272_issues_edit_g_project_management_issue_iteration_changed.yml
deleted file mode 100644
index 7e755c6e0e9e2..0000000000000
--- a/config/events/1656555272_issues_edit_g_project_management_issue_iteration_changed.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-description: Issue's iteration was changed
-category: issues_edit
-action: g_project_management_issue_iteration_changed
-identifiers:
-  - project
-  - user
-  - namespace
-product_section: dev
-product_stage: plan
-product_group: project_management
-product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
-distributions:
-  - ee
-tiers:
-  - premium
-  - ultimate
-
diff --git a/config/events/1656555342_issues_edit_g_project_management_issue_removed_from_epic.yml b/config/events/1656555342_issues_edit_g_project_management_issue_removed_from_epic.yml
deleted file mode 100644
index 5241e48ee9f70..0000000000000
--- a/config/events/1656555342_issues_edit_g_project_management_issue_removed_from_epic.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-description: An issue was removed from an epic
-category: issues_edit
-action: g_project_management_issue_removed_from_epic
-identifiers:
-  - project
-  - user
-  - namespace
-product_section: dev
-product_stage: plan
-product_group: project_management
-product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
-distributions:
-  - ee
-tiers:
-  - premium
-  - ultimate
-
diff --git a/config/events/1656555426_issues_edit_g_project_management_issue_weight_changed.yml b/config/events/1656555426_issues_edit_g_project_management_issue_weight_changed.yml
deleted file mode 100644
index 99492d5017669..0000000000000
--- a/config/events/1656555426_issues_edit_g_project_management_issue_weight_changed.yml
+++ /dev/null
@@ -1,20 +0,0 @@
----
-description: Issue's weight was changed
-category: issues_edit
-action: g_project_management_issue_weight_changed
-identifiers:
-  - project
-  - user
-  - namespace
-product_section: dev
-product_stage: plan
-product_group: project_management
-product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
-distributions:
-  - ee
-tiers:
-  - premium
-  - ultimate
-
diff --git a/config/events/1656554755_issues_edit_g_project_management_issue_added_to_epic.yml b/config/events/1659067369_issue_actions_perform_issue_acitons_.yml
similarity index 57%
rename from config/events/1656554755_issues_edit_g_project_management_issue_added_to_epic.yml
rename to config/events/1659067369_issue_actions_perform_issue_acitons_.yml
index 0c1ea4584e1ca..77fabfa2d6a56 100644
--- a/config/events/1656554755_issues_edit_g_project_management_issue_added_to_epic.yml
+++ b/config/events/1659067369_issue_actions_perform_issue_acitons_.yml
@@ -1,20 +1,25 @@
 ---
-description: Issue was added to an epic
+description: Issue usage event
 category: issues_edit
-action: g_project_management_issue_added_to_epic
+action: perform_issue_action
+label_description:
+property_description: the name of the performed action
+value_description:
+extra_properties:
 identifiers:
+  - namespace
   - project
   - user
-  - namespace
 product_section: dev
 product_stage: plan
 product_group: project_management
 product_category: issue_tracking
-milestone: "15.2"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91443
+milestone: "15.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91659
 distributions:
+  - ce
   - ee
 tiers:
+  - free
   - premium
   - ultimate
-
diff --git a/ee/app/services/ee/issues/base_service.rb b/ee/app/services/ee/issues/base_service.rb
index 0eadc5c80736c..1b3addb5bd8b2 100644
--- a/ee/app/services/ee/issues/base_service.rb
+++ b/ee/app/services/ee/issues/base_service.rb
@@ -28,9 +28,11 @@ def assign_epic(issue, epic)
           next unless result[:status] == :success
 
           if had_epic
-            ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_changed_epic_action(author: current_user, project: project)
+            ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_changed_epic_action(author: current_user,
+                                                                                                    project: project)
           else
-            ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_added_to_epic_action(author: current_user, project: project)
+            ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_added_to_epic_action(author: current_user,
+                                                                                                     project: project)
           end
         end
       end
diff --git a/ee/app/services/ee/issues/move_service.rb b/ee/app/services/ee/issues/move_service.rb
index 4a9f3344da5c7..5d82e7f5d9d59 100644
--- a/ee/app/services/ee/issues/move_service.rb
+++ b/ee/app/services/ee/issues/move_service.rb
@@ -24,7 +24,8 @@ def rewrite_epic_issue
 
         original_entity.reset
 
-        ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_changed_epic_action(author: current_user, project: target_project)
+        ::Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_changed_epic_action(author: current_user,
+                                                                                                project: target_project)
       end
 
       def log_error_for(epic_issue)
diff --git a/ee/app/services/resource_events/change_weight_service.rb b/ee/app/services/resource_events/change_weight_service.rb
index 766a962efc964..a50acba3830bb 100644
--- a/ee/app/services/resource_events/change_weight_service.rb
+++ b/ee/app/services/resource_events/change_weight_service.rb
@@ -16,7 +16,8 @@ def execute
       if resource.is_a?(WorkItem)
         Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter.track_work_item_weight_changed_action(author: user)
       else
-        Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_weight_changed_action(author: user, project: resource.project)
+        Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_weight_changed_action(author: user,
+                                                                                                project: resource.project)
       end
     end
 
diff --git a/ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb b/ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb
index 1f0c5fab39b87..4e8d7ab1f1c94 100644
--- a/ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb
+++ b/ee/spec/lib/ee/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb
@@ -6,9 +6,14 @@
   let_it_be(:user1) { build(:user, id: 1) }
   let_it_be(:user2) { build(:user, id: 2) }
   let_it_be(:project) { build(:project) }
+  let_it_be(:category) { described_class::ISSUE_CATEGORY }
+  let_it_be(:event_action) { described_class::ISSUE_ACTION }
+  let_it_be(:event_label) { described_class::ISSUE_LABEL }
+
+  let(:event_property) { action }
 
   context 'for Issue health status changed actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_HEALTH_STATUS_CHANGED }
 
       def track_action(params)
@@ -18,7 +23,7 @@ def track_action(params)
   end
 
   context 'for Issue iteration changed actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_ITERATION_CHANGED }
 
       def track_action(params)
@@ -28,7 +33,7 @@ def track_action(params)
   end
 
   context 'for Issue weight changed actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_WEIGHT_CHANGED }
 
       def track_action(params)
@@ -38,7 +43,7 @@ def track_action(params)
   end
 
   context 'for Issue added to epic actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_ADDED_TO_EPIC }
 
       def track_action(params)
@@ -48,7 +53,7 @@ def track_action(params)
   end
 
   context 'for Issue removed from epic actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_REMOVED_FROM_EPIC }
 
       def track_action(params)
@@ -58,7 +63,7 @@ def track_action(params)
   end
 
   context 'for Issue changed epic actions' do
-    it_behaves_like 'a daily tracked issuable snowplow and service ping events' do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let_it_be(:action) { described_class::ISSUE_CHANGED_EPIC }
 
       def track_action(params)
diff --git a/ee/spec/models/resource_iteration_event_spec.rb b/ee/spec/models/resource_iteration_event_spec.rb
index e133158584dbd..ee081048f9f9c 100644
--- a/ee/spec/models/resource_iteration_event_spec.rb
+++ b/ee/spec/models/resource_iteration_event_spec.rb
@@ -16,15 +16,12 @@
   # from https://gitlab.com/gitlab-org/gitlab/-/issues/365960
   describe 'when creating an issue' do
     let(:issue) { create(:issue) }
-    let(:subject) { create(described_class.name.underscore.to_sym, issue: issue) }
 
-    it_behaves_like 'Snowplow event tracking' do
-      let(:user) { issue.author }
-      let(:category) { 'issues_edit' }
-      let(:action) { 'g_project_management_issue_iteration_changed' }
+    it_behaves_like 'issue_edit snowplow tracking' do
+      let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ITERATION_CHANGED }
       let(:project) { issue.project }
-      let(:namespace) { project.namespace }
-      let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+      let(:user) { issue.author }
+      subject(:service_action) { create(described_class.name.underscore.to_sym, issue: issue) }
     end
   end
 
diff --git a/ee/spec/services/ee/issues/clone_service_spec.rb b/ee/spec/services/ee/issues/clone_service_spec.rb
index 504208b01423f..ba7e9ec89eb4e 100644
--- a/ee/spec/services/ee/issues/clone_service_spec.rb
+++ b/ee/spec/services/ee/issues/clone_service_spec.rb
@@ -58,18 +58,15 @@
 
         describe 'events tracking', :snowplow do
           it 'tracks usage data for changed epic action' do
-            expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action).with(author: user,
-                                                                                                                            project: new_project)
+            expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action)
+                                                                               .with(author: user, project: new_project)
 
             subject
           end
 
-          it_behaves_like 'Snowplow event tracking' do
-            let(:category) { 'issues_edit' }
-            let(:action) { 'g_project_management_issue_changed_epic' }
-            let(:namespace) { new_project.namespace }
+          it_behaves_like 'issue_edit snowplow tracking' do
+            let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CHANGED_EPIC }
             let(:project) { new_project }
-            let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
           end
         end
 
diff --git a/ee/spec/services/ee/issues/move_service_spec.rb b/ee/spec/services/ee/issues/move_service_spec.rb
index 1ec7695e06552..e14bacb8a91dc 100644
--- a/ee/spec/services/ee/issues/move_service_spec.rb
+++ b/ee/spec/services/ee/issues/move_service_spec.rb
@@ -114,20 +114,18 @@
         end
 
         it 'tracks usage data for changed epic action' do
-          expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action).with(author: user,
-                                                                                                                          project: new_project)
+          expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action)
+                                                                             .with(author: user, project: new_project)
 
           subject
         end
 
-        it_behaves_like 'Snowplow event tracking' do
-          let(:category) { 'issues_edit' }
-          let(:action) { 'g_project_management_issue_changed_epic' }
+        it_behaves_like 'issue_edit snowplow tracking' do
+          let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CHANGED_EPIC }
           let(:project) { new_project }
-          let(:namespace) { new_project.namespace }
-          let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
         end
       end
+
       context 'user can not update the epic' do
         it 'ignores epic issue reference' do
           new_issue = move_service.execute(old_issue, new_project)
diff --git a/ee/spec/services/ee/issues/update_service_spec.rb b/ee/spec/services/ee/issues/update_service_spec.rb
index 8828871218218..c5eff9d146e26 100644
--- a/ee/spec/services/ee/issues/update_service_spec.rb
+++ b/ee/spec/services/ee/issues/update_service_spec.rb
@@ -313,11 +313,8 @@ def update_issue(opts)
               subject
             end
 
-            it_behaves_like 'Snowplow event tracking' do
-              let(:category) { 'issues_edit' }
-              let(:action) { 'g_project_management_issue_added_to_epic' }
-              let(:namespace) { project.namespace }
-              let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+            it_behaves_like 'issue_edit snowplow tracking' do
+              let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ADDED_TO_EPIC }
             end
           end
         end
@@ -345,18 +342,14 @@ def update_issue(opts)
 
           describe 'events tracking', :snowplow do
             it 'tracks usage data for changed epic action' do
-              expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action).with(author: user,
-                                                                                                                              project: issue.project)
+              expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_changed_epic_action)
+                                                                                 .with(author: user, project: project)
 
               subject
             end
 
-            it_behaves_like 'Snowplow event tracking' do
-              let(:category) { 'issues_edit' }
-              let(:action) { 'g_project_management_issue_changed_epic' }
-              let(:namespace) { issue.project.namespace }
-              let(:project) { issue.project }
-              let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+            it_behaves_like 'issue_edit snowplow tracking' do
+              let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CHANGED_EPIC }
             end
           end
         end
@@ -466,11 +459,8 @@ def update_issue(opts)
               subject
             end
 
-            it_behaves_like 'Snowplow event tracking' do
-              let(:category) { 'issues_edit' }
-              let(:action) { 'g_project_management_issue_removed_from_epic' }
-              let(:namespace) { project.namespace }
-              let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+            it_behaves_like 'issue_edit snowplow tracking' do
+              let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_REMOVED_FROM_EPIC }
             end
           end
 
diff --git a/ee/spec/services/ee/system_notes/issuables_service_spec.rb b/ee/spec/services/ee/system_notes/issuables_service_spec.rb
index 312ddc1af5ce0..15738455feb1e 100644
--- a/ee/spec/services/ee/system_notes/issuables_service_spec.rb
+++ b/ee/spec/services/ee/system_notes/issuables_service_spec.rb
@@ -48,12 +48,9 @@
         subject
       end
 
-      it_behaves_like 'Snowplow event tracking' do
-        let(:category) { 'issues_edit' }
-        let(:action) { 'g_project_management_issue_health_status_changed' }
-        let(:namespace) { project.namespace }
+      it_behaves_like 'issue_edit snowplow tracking' do
+        let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_HEALTH_STATUS_CHANGED }
         let(:user) { author }
-        let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
       end
     end
   end
diff --git a/ee/spec/services/resource_events/change_weight_service_spec.rb b/ee/spec/services/resource_events/change_weight_service_spec.rb
index ca9ea176e42fa..76d68344e99d8 100644
--- a/ee/spec/services/resource_events/change_weight_service_spec.rb
+++ b/ee/spec/services/resource_events/change_weight_service_spec.rb
@@ -74,12 +74,9 @@
       end
     end
 
-    it_behaves_like 'Snowplow event tracking' do
-      let(:category) { 'issues_edit' }
-      let(:action) { 'g_project_management_issue_weight_changed' }
-      let(:namespace) { issue.project.namespace }
+    it_behaves_like 'issue_edit snowplow tracking' do
+      let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_WEIGHT_CHANGED }
       let(:project) { issue.project }
-      let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
     end
   end
 
diff --git a/ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb b/ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb
index 51fbf0415e91e..7eb0eb59df9fa 100644
--- a/ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb
+++ b/ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb
@@ -73,12 +73,9 @@
           execute
         end
 
-        it_behaves_like 'Snowplow event tracking' do
-          let(:subject) { execute }
-          let(:category) { 'issues_edit' }
-          let(:action) { 'g_project_management_issue_added_to_epic' }
-          let(:namespace) { project.namespace }
-          let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+        it_behaves_like 'issue_edit snowplow tracking' do
+          let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ADDED_TO_EPIC }
+          subject(:service_action) { execute }
         end
       end
     end
@@ -129,12 +126,9 @@
           execute
         end
 
-        it_behaves_like 'Snowplow event tracking' do
-          let(:subject) { execute }
-          let(:category) { 'issues_edit' }
-          let(:action) { 'g_project_management_issue_added_to_epic' }
-          let(:namespace) { project.namespace }
-          let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+        it_behaves_like 'issue_edit snowplow tracking' do
+          let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ADDED_TO_EPIC }
+          subject(:service_action) { execute }
         end
       end
     end
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 9d463e11772af..316d9bb3dc199 100644
--- a/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb
+++ b/lib/gitlab/usage_data_counters/issue_activity_unique_counter.rb
@@ -4,6 +4,8 @@ module Gitlab
   module UsageDataCounters
     module IssueActivityUniqueCounter
       ISSUE_CATEGORY = 'issues_edit'
+      ISSUE_ACTION = 'perform_issue_action'
+      ISSUE_LABEL = 'redis_hll_counters.issues_edit.issues_edit_total_unique_counts_monthly'
 
       ISSUE_ASSIGNEE_CHANGED = 'g_project_management_issue_assignee_changed'
       ISSUE_CREATED = 'g_project_management_issue_created'
@@ -126,42 +128,48 @@ def track_issue_time_spent_changed_action(author:)
           track_unique_action(ISSUE_TIME_SPENT_CHANGED, author)
         end
 
-        def track_issue_comment_added_action(author:)
+        def track_issue_comment_added_action(author:, project:)
+          track_snowplow_action(ISSUE_COMMENT_ADDED, author, project)
           track_unique_action(ISSUE_COMMENT_ADDED, author)
         end
 
-        def track_issue_comment_edited_action(author:)
+        def track_issue_comment_edited_action(author:, project:)
+          track_snowplow_action(ISSUE_COMMENT_EDITED, author, project)
           track_unique_action(ISSUE_COMMENT_EDITED, author)
         end
 
-        def track_issue_comment_removed_action(author:)
+        def track_issue_comment_removed_action(author:, project:)
+          track_snowplow_action(ISSUE_COMMENT_REMOVED, author, project)
           track_unique_action(ISSUE_COMMENT_REMOVED, author)
         end
 
-        def track_issue_cloned_action(author:)
+        def track_issue_cloned_action(author:, project:)
+          track_snowplow_action(ISSUE_CLONED, author, project)
           track_unique_action(ISSUE_CLONED, author)
         end
 
         private
 
-        def track_unique_action(action, author)
-          return unless author
-
-          Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id)
-        end
-
         def track_snowplow_action(action, author, project)
-          return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project&.namespace)
+          return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project.namespace)
           return unless author
 
           Gitlab::Tracking.event(
             ISSUE_CATEGORY,
-            action.to_s,
+            ISSUE_ACTION,
+            label: ISSUE_LABEL,
+            property: action,
             project: project,
-            namespace: project&.namespace,
+            namespace: project.namespace,
             user: author
           )
         end
+
+        def track_unique_action(action, author)
+          return unless author
+
+          Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id)
+        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 1b73e5269d76c..84a6f33828283 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
@@ -6,7 +6,12 @@
   let_it_be(:user1) { build(:user, id: 1) }
   let_it_be(:user2) { build(:user, id: 2) }
   let_it_be(:user3) { build(:user, id: 3) }
+  let_it_be(:project) { build(:project) }
+  let_it_be(:category) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CATEGORY }
+  let_it_be(:event_action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ACTION }
+  let_it_be(:event_label) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_LABEL }
 
+  let(:event_property) { action }
   let(:time) { Time.zone.now }
 
   context 'for Issue title edit actions' do
@@ -120,8 +125,8 @@ def track_action(params)
   end
 
   context 'for Issue cloned actions' do
-    it_behaves_like 'a daily tracked issuable event' do
-      let(:action) { described_class::ISSUE_CLONED }
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
+      let_it_be(:action) { described_class::ISSUE_CLONED }
 
       def track_action(params)
         described_class.track_issue_cloned_action(**params)
@@ -239,8 +244,8 @@ def track_action(params)
     end
   end
 
-  context 'for Issue comment added actions' do
-    it_behaves_like 'a daily tracked issuable event' do
+  context 'for Issue comment added actions', :snowplow do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let(:action) { described_class::ISSUE_COMMENT_ADDED }
 
       def track_action(params)
@@ -249,8 +254,8 @@ def track_action(params)
     end
   end
 
-  context 'for Issue comment edited actions' do
-    it_behaves_like 'a daily tracked issuable event' do
+  context 'for Issue comment edited actions', :snowplow do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let(:action) { described_class::ISSUE_COMMENT_EDITED }
 
       def track_action(params)
@@ -259,8 +264,8 @@ def track_action(params)
     end
   end
 
-  context 'for Issue comment removed actions' do
-    it_behaves_like 'a daily tracked issuable event' do
+  context 'for Issue comment removed actions', :snowplow do
+    it_behaves_like 'daily tracked issuable snowplow and service ping events with project' do
       let(:action) { described_class::ISSUE_COMMENT_REMOVED }
 
       def track_action(params)
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 53b75a3c99145..ed64663260ee7 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -69,20 +69,31 @@
         end
       end
 
-      it 'tracks issue comment usage data', :clean_gitlab_redis_shared_state do
-        event = Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_ADDED
-        counter = Gitlab::UsageDataCounters::HLLRedisCounter
+      describe 'event tracking', :snowplow do
+        let(:event) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_ADDED }
+        let(:execute_create_service) { described_class.new(project, user, opts).execute }
 
-        expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_added_action).with(author: user).and_call_original
-        expect do
-          described_class.new(project, user, opts).execute
-        end.to change { counter.unique_events(event_names: event, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
-      end
+        it 'tracks issue comment usage data', :clean_gitlab_redis_shared_state do
+          counter = Gitlab::UsageDataCounters::HLLRedisCounter
 
-      it 'does not track merge request usage data' do
-        expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).not_to receive(:track_create_comment_action)
+          expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_added_action)
+                                                                             .with(author: user, project: project)
+                                                                             .and_call_original
+          expect do
+            execute_create_service
+          end.to change { counter.unique_events(event_names: event, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
+        end
 
-        described_class.new(project, user, opts).execute
+        it 'does not track merge request usage data' do
+          expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).not_to receive(:track_create_comment_action)
+
+          execute_create_service
+        end
+
+        it_behaves_like 'issue_edit snowplow tracking' do
+          let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_ADDED }
+          subject(:service_action) { execute_create_service }
+        end
       end
 
       context 'in a merge request' do
diff --git a/spec/services/notes/destroy_service_spec.rb b/spec/services/notes/destroy_service_spec.rb
index 55acdabef8235..be95a4bb181ee 100644
--- a/spec/services/notes/destroy_service_spec.rb
+++ b/spec/services/notes/destroy_service_spec.rb
@@ -25,15 +25,25 @@
         .to change { user.todos_pending_count }.from(1).to(0)
     end
 
-    it 'tracks issue comment removal usage data', :clean_gitlab_redis_shared_state do
-      note = create(:note, project: project, noteable: issue)
-      event = Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_REMOVED
-      counter = Gitlab::UsageDataCounters::HLLRedisCounter
+    describe 'comment removed event tracking', :snowplow do
+      let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_REMOVED }
+      let(:note) { create(:note, project: project, noteable: issue) }
+      let(:service_action) { described_class.new(project, user).execute(note) }
+
+      it 'tracks issue comment removal usage data', :clean_gitlab_redis_shared_state do
+        counter = Gitlab::UsageDataCounters::HLLRedisCounter
+
+        expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_removed_action)
+                                                                           .with(author: user, project: project)
+                                                                           .and_call_original
+        expect do
+          service_action
+        end.to change { counter.unique_events(event_names: property, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
+      end
 
-      expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_removed_action).with(author: user).and_call_original
-      expect do
-        described_class.new(project, user).execute(note)
-      end.to change { counter.unique_events(event_names: event, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
+      it_behaves_like 'issue_edit snowplow tracking' do
+        subject(:execute_service_action) { service_action }
+      end
     end
 
     it 'tracks merge request usage data' do
diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb
index ae7bea30944ad..989ca7b8df18c 100644
--- a/spec/services/notes/update_service_spec.rb
+++ b/spec/services/notes/update_service_spec.rb
@@ -47,21 +47,31 @@ def update_note(opts)
       end
     end
 
-    it 'does not track usage data when params is blank' do
-      expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_comment_edited_action)
-      expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).not_to receive(:track_edit_comment_action)
+    describe 'event tracking', :snowplow do
+      let(:event) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_EDITED }
 
-      update_note({})
-    end
+      it 'does not track usage data when params is blank' do
+        expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_comment_edited_action)
+        expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter).not_to receive(:track_edit_comment_action)
 
-    it 'tracks issue usage data', :clean_gitlab_redis_shared_state do
-      event = Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_EDITED
-      counter = Gitlab::UsageDataCounters::HLLRedisCounter
+        update_note({})
+      end
 
-      expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_edited_action).with(author: user).and_call_original
-      expect do
-        update_note(note: 'new text')
-      end.to change { counter.unique_events(event_names: event, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
+      it 'tracks issue usage data', :clean_gitlab_redis_shared_state do
+        counter = Gitlab::UsageDataCounters::HLLRedisCounter
+
+        expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_comment_edited_action)
+                                                                           .with(author: user, project: project)
+                                                                           .and_call_original
+        expect do
+          update_note(note: 'new text')
+        end.to change { counter.unique_events(event_names: event, start_date: 1.day.ago, end_date: 1.day.from_now) }.by(1)
+      end
+
+      it_behaves_like 'issue_edit snowplow tracking' do
+        let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_COMMENT_EDITED }
+        subject(:service_action) { update_note(note: 'new text') }
+      end
     end
 
     context 'when note text was changed' do
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb
index 70f6ce8926c7e..d0e68bf0ddbb4 100644
--- a/spec/services/system_notes/issuables_service_spec.rb
+++ b/spec/services/system_notes/issuables_service_spec.rb
@@ -712,15 +712,20 @@ def build_note(added_count, removed_count)
         end
       end
 
-      context 'cloned to' do
+      context 'cloned to', :snowplow do
         let(:direction) { :to }
 
         it 'tracks usage' do
           expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter)
-            .to receive(:track_issue_cloned_action).with(author: author)
+            .to receive(:track_issue_cloned_action).with(author: author, project: project )
 
           subject
         end
+
+        it_behaves_like 'issue_edit snowplow tracking' do
+          let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CLONED }
+          let(:user) { author }
+        end
       end
     end
   end
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 c2b26d4decd49..481e11bcf0ec1 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
@@ -74,12 +74,10 @@ def count_unique(date_from: 1.minute.ago, date_to: 1.minute.from_now)
   end
 end
 
-RSpec.shared_examples 'a daily tracked issuable snowplow and service ping events' do
+RSpec.shared_examples 'daily tracked issuable snowplow and service ping events with project' do
   it_behaves_like 'a daily tracked issuable snowplow and service ping events for given event params' do
-    let_it_be(:track_params) { { project: project } }
-    let_it_be(:event_params) { track_params.merge(namespace: project.namespace) }
-    let_it_be(:category) { 'issues_edit' }
-    let_it_be(:event_action) { action }
+    let(:track_params) { { project: project } }
+    let(:event_params) { track_params.merge(label: event_label, property: event_property, namespace: project.namespace) }
   end
 end
 
diff --git a/spec/support/shared_examples/services/snowplow_tracking_shared_examples.rb b/spec/support/shared_examples/services/snowplow_tracking_shared_examples.rb
new file mode 100644
index 0000000000000..0687be6f429c0
--- /dev/null
+++ b/spec/support/shared_examples/services/snowplow_tracking_shared_examples.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+shared_examples 'issue_edit snowplow tracking' do
+  let(:category) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CATEGORY }
+  let(:action) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_ACTION }
+  let(:label) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_LABEL }
+  let(:namespace) { project.namespace }
+  let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+
+  it_behaves_like 'Snowplow event tracking'
+end
-- 
GitLab