From c0d2c498114e955bad2f6daf5cabb070c307062c Mon Sep 17 00:00:00 2001
From: Alina Mihaila <amihaila@gitlab.com>
Date: Thu, 22 Oct 2020 12:33:01 +0000
Subject: [PATCH] Add basic structure for usage data

  - Add license, settings, counts_weekly,
    top level keys to usage data
  - Add docs for placing metrics
  - Add change log file
  - This will make a basic structure to use
    for any metric added to usage data payload
---
 ...count_28d-top-level-keys-to-usage-data.yml |  5 ++
 .../product_analytics/usage_ping.md           | 28 ++++++----
 lib/gitlab/usage_data.rb                      | 21 ++++++++
 spec/lib/gitlab/usage_data_spec.rb            | 52 ++++++++++---------
 4 files changed, 72 insertions(+), 34 deletions(-)
 create mode 100644 changelogs/unreleased/251011-add-count_all-count_7d-count_28d-top-level-keys-to-usage-data.yml

diff --git a/changelogs/unreleased/251011-add-count_all-count_7d-count_28d-top-level-keys-to-usage-data.yml b/changelogs/unreleased/251011-add-count_all-count_7d-count_28d-top-level-keys-to-usage-data.yml
new file mode 100644
index 0000000000000..114752547b456
--- /dev/null
+++ b/changelogs/unreleased/251011-add-count_all-count_7d-count_28d-top-level-keys-to-usage-data.yml
@@ -0,0 +1,5 @@
+---
+title: Add basic top level keys license, settings, and counts_weekly for usage data payload
+merge_request: 45540
+author:
+type: added
diff --git a/doc/development/product_analytics/usage_ping.md b/doc/development/product_analytics/usage_ping.md
index d482af77d8a8e..5d887346f073b 100644
--- a/doc/development/product_analytics/usage_ping.md
+++ b/doc/development/product_analytics/usage_ping.md
@@ -548,7 +548,17 @@ for how to use its API to query for data.
 
 ## Developing and testing Usage Ping
 
-### 1. Use your Rails console to manually test counters
+### 1. Naming and placing the metrics
+
+Add the metric in one of the top level keys
+
+- `license`: for license related metrics.
+- `settings`: for settings related metrics.
+- `counts_weekly`: for counters that have data for the most recent 7 days.
+- `counts_monthly`: for counters that have data for the most recent 28 days.
+- `counts`: for counters that have data for all time.
+
+### 2. Use your Rails console to manually test counters
 
 ```ruby
 # count
@@ -560,7 +570,7 @@ Gitlab::UsageData.distinct_count(::Project, :creator_id)
 Gitlab::UsageData.distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
 ```
 
-### 2. Generate the SQL query
+### 3. Generate the SQL query
 
 Your Rails console will return the generated SQL queries.
 
@@ -574,7 +584,7 @@ pry(main)> Gitlab::UsageData.count(User.active)
    (1.9ms)  SELECT COUNT("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4)) AND "users"."id" BETWEEN 1 AND 100000
 ```
 
-### 3. Optimize queries with #database-lab
+### 4. Optimize queries with #database-lab
 
 Paste the SQL query into `#database-lab` to see how the query performs at scale.
 
@@ -601,27 +611,27 @@ We also use `#database-lab` and [explain.depesz.com](https://explain.depesz.com/
 - Avoid joins and write the queries as simply as possible, [example](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36316).
 - Set a custom `batch_size` for `distinct_count`, [example](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38000).
 
-### 4. Add the metric definition
+### 5. Add the metric definition
 
 When adding, changing, or updating metrics, please update the [Event Dictionary's **Usage Ping** table](event_dictionary.md).
 
-### 5. Add new metric to Versions Application
+### 6. Add new metric to Versions Application
 
 Check if new metrics need to be added to the Versions Application. See `usage_data` [schema](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L147) and usage data [parameters accepted](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column.
 
-### 6. Add the feature label
+### 7. Add the feature label
 
 Add the `feature` label to the Merge Request for new Usage Ping metrics. These are user-facing changes and are part of expanding the Usage Ping feature.
 
-### 7. Add a changelog file
+### 8. Add a changelog file
 
 Ensure you comply with the [Changelog entries guide](../changelog.md).
 
-### 8. Ask for a Product Analytics Review
+### 9. Ask for a Product Analytics Review
 
 On GitLab.com, we have DangerBot setup to monitor Product Analytics related files and DangerBot will recommend a Product Analytics review. Mention `@gitlab-org/growth/product_analytics/engineers` in your MR for a review.
 
-### 9. Verify your metric
+### 10. Verify your metric
 
 On GitLab.com, the Product Analytics team regularly monitors Usage Ping. They may alert you that your metrics need further optimization to run quicker and with greater success. You may also use the [Usage Ping QA dashboard](https://app.periscopedata.com/app/gitlab/632033/Usage-Ping-QA) to check how well your metric performs. The dashboard allows filtering by GitLab version, by "Self-managed" & "Saas" and shows you how many failures have occurred for each metric. Whenever you notice a high failure rate, you may re-optimize your metric.
 
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index afe430c68524b..e7e1ee949e623 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -40,8 +40,11 @@ def uncached_data
 
         with_finished_at(:recording_ce_finished_at) do
           license_usage_data
+            .merge(system_usage_data_license)
+            .merge(system_usage_data_settings)
             .merge(system_usage_data)
             .merge(system_usage_data_monthly)
+            .merge(system_usage_data_weekly)
             .merge(features_usage_data)
             .merge(components_usage_data)
             .merge(cycle_analytics_usage_data)
@@ -222,6 +225,24 @@ def system_usage_data_monthly
       end
       # rubocop: enable CodeReuse/ActiveRecord
 
+      def system_usage_data_license
+        {
+          license: {}
+        }
+      end
+
+      def system_usage_data_settings
+        {
+          settings: {}
+        }
+      end
+
+      def system_usage_data_weekly
+        {
+          counts_weekly: {}
+        }
+      end
+
       def cycle_analytics_usage_data
         Gitlab::CycleAnalytics::UsageData.new.to_json
       rescue ActiveRecord::StatementInvalid
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index ad49962096a82..7f5d41e71a20d 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -12,33 +12,35 @@
   end
 
   describe '.uncached_data' do
-    describe '.usage_activity_by_stage' do
-      subject { described_class.uncached_data }
-
-      it 'includes usage_activity_by_stage data' do
-        is_expected.to include(:usage_activity_by_stage)
-        is_expected.to include(:usage_activity_by_stage_monthly)
-        expect(subject[:usage_activity_by_stage])
-          .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify)
-        expect(subject[:usage_activity_by_stage_monthly])
-          .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify)
-      end
-
-      it 'clears memoized values' do
-        allow(described_class).to receive(:clear_memoization)
+    subject { described_class.uncached_data }
+
+    it 'includes basic top and second level keys' do
+      is_expected.to include(:counts)
+      is_expected.to include(:counts_monthly)
+      is_expected.to include(:counts_weekly)
+      is_expected.to include(:license)
+      is_expected.to include(:settings)
+
+      # usage_activity_by_stage data
+      is_expected.to include(:usage_activity_by_stage)
+      is_expected.to include(:usage_activity_by_stage_monthly)
+      expect(subject[:usage_activity_by_stage])
+        .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify)
+      expect(subject[:usage_activity_by_stage_monthly])
+        .to include(:configure, :create, :manage, :monitor, :plan, :release, :verify)
+      expect(subject[:usage_activity_by_stage][:create])
+        .not_to include(:merge_requests_users)
+      expect(subject[:usage_activity_by_stage_monthly][:create])
+        .to include(:merge_requests_users)
+    end
 
-        subject
+    it 'clears memoized values' do
+      allow(described_class).to receive(:clear_memoization)
 
-        described_class::CE_MEMOIZED_VALUES.each do |key|
-          expect(described_class).to have_received(:clear_memoization).with(key)
-        end
-      end
+      subject
 
-      it 'merge_requests_users is included only in montly counters' do
-        expect(subject[:usage_activity_by_stage][:create])
-          .not_to include(:merge_requests_users)
-        expect(subject[:usage_activity_by_stage_monthly][:create])
-          .to include(:merge_requests_users)
+      described_class::CE_MEMOIZED_VALUES.each do |key|
+        expect(described_class).to have_received(:clear_memoization).with(key)
       end
     end
 
@@ -48,7 +50,7 @@
       end
       expect(described_class).to receive(:recorded_at).and_raise(Exception.new('Stopped calculating recorded_at'))
 
-      expect { described_class.uncached_data }.to raise_error('Stopped calculating recorded_at')
+      expect { subject }.to raise_error('Stopped calculating recorded_at')
     end
   end
 
-- 
GitLab