Commit c0d2c498 authored by Alina Mihaila's avatar Alina Mihaila Committed by Alper Akgun

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
parent 86836c3d
---
title: Add basic top level keys license, settings, and counts_weekly for usage data payload
merge_request: 45540
author:
type: added
......@@ -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.
......
......@@ -40,8 +40,11 @@ module Gitlab
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 @@ module Gitlab
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
......
......@@ -12,33 +12,35 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
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 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment