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 0000000000000000000000000000000000000000..114752547b456dfa12a87566d1517b2ecc2564c6 --- /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 d482af77d8a8ea901062a8cd7da34fd12a72bedd..5d887346f073b69e06c311cd8e662c3e915d9b09 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 afe430c68524b05b9453c01f5604d233a34736fb..e7e1ee949e623ac040a28331a5e35cc8b6c97e08 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 ad49962096a8283e4f8449cd9021775362ce3bf2..7f5d41e71a20dae9185d8533f7987de43eb9ffe0 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