Commit 331c665c authored by Kerri Miller's avatar Kerri Miller

Merge branch 'mwaw/product_analytics_aggregated_metrics_with_feature_flags' into 'master'

Add feature flag mechanism to aggregated metrics

See merge request gitlab-org/gitlab!47534
parents 2aab1d55 83971d64
...@@ -737,13 +737,20 @@ In order to add data for aggregated metrics into Usage Ping payload you should a ...@@ -737,13 +737,20 @@ In order to add data for aggregated metrics into Usage Ping payload you should a
- operator: operator that defines how aggregated metric data will be counted. Available operators are: - operator: operator that defines how aggregated metric data will be counted. Available operators are:
- `ANY`: removes duplicates and counts all entries that triggered any of listed events - `ANY`: removes duplicates and counts all entries that triggered any of listed events
- events: list of events names (from [`known_events.yml`](#known-events-in-usage-data-payload)) to aggregate into metric. All events in this list must have the same `redis_slot` and `aggregation` attributes. - events: list of events names (from [`known_events.yml`](#known-events-in-usage-data-payload)) to aggregate into metric. All events in this list must have the same `redis_slot` and `aggregation` attributes.
- feature_flag: name of [development feature flag](../feature_flags/development.md#development-type) that will be checked before
metrics aggregation is performed. Corresponding feature flag should have `default_enabled` attribute set to `false`.
`feature_flag` attribute is **OPTIONAL** and can be omitted, when `feature_flag` is missing no feature flag will be checked.
Example aggregated metric entry: Example aggregated metric entries:
```yaml ```yaml
- name: example_aggregated_metric - name: example_aggregated_metric
operator: ANY
events: ['i_search_advanced', 'i_search_paid']
- name: example_aggregated_metric_with_feautre_flag
operator: ANY operator: ANY
events: ['i_search_total', 'i_search_advanced', 'i_search_paid'] events: ['i_search_total', 'i_search_advanced', 'i_search_paid']
feature_flag: example_aggregated_metric
``` ```
Aggregated metrics will be added under `aggregated_metrics` key in both `counts_weekly` and `counts_monthly` top level keys in Usage Ping payload. Aggregated metrics will be added under `aggregated_metrics` key in both `counts_weekly` and `counts_monthly` top level keys in Usage Ping payload.
......
...@@ -4,10 +4,15 @@ ...@@ -4,10 +4,15 @@
# - "ALL": counts unique elements that were observed triggering all of following events # - "ALL": counts unique elements that were observed triggering all of following events
# events: list of events names to aggregate into metric. All events in this list must have the same 'redis_slot' and 'aggregation' attributes # events: list of events names to aggregate into metric. All events in this list must have the same 'redis_slot' and 'aggregation' attributes
# see from lib/gitlab/usage_data_counters/known_events/ for the list of valid events. # see from lib/gitlab/usage_data_counters/known_events/ for the list of valid events.
# feature_flag: name of development feature flag that will be checked before metrics aggregation is performed.
# Corresponding feature flag should have `default_enabled` attribute set to `false`.
# This attribute is OPTIONAL and can be omitted, when `feature_flag` is missing no feature flag will be checked.
--- ---
- name: product_analytics_test_aggregated_metrics - name: product_analytics_test_aggregated_metrics
operator: ANY operator: ANY
events: ['i_search_total', 'i_search_advanced', 'i_search_paid'] events: ['i_search_total', 'i_search_advanced', 'i_search_paid']
feature_flag: product_analytics_aggregated_metrics
- name: product_analytics_test_combined_events - name: product_analytics_test_combined_events
operator: ALL operator: ALL
events: ['i_search_total', 'i_search_advanced', 'i_search_paid'] events: ['i_search_total', 'i_search_advanced', 'i_search_paid']
feature_flag: product_analytics_aggregated_metrics
...@@ -97,15 +97,11 @@ module Gitlab ...@@ -97,15 +97,11 @@ module Gitlab
end end
def aggregated_metrics_monthly_data def aggregated_metrics_monthly_data
aggregated_metrics.to_h do |aggregation| aggregated_metrics_data(4.weeks.ago.to_date)
[aggregation[:name], calculate_count_for_aggregation(aggregation, start_date: 4.weeks.ago.to_date, end_date: Date.current)]
end
end end
def aggregated_metrics_weekly_data def aggregated_metrics_weekly_data
aggregated_metrics.to_h do |aggregation| aggregated_metrics_data(7.days.ago.to_date)
[aggregation[:name], calculate_count_for_aggregation(aggregation, start_date: 7.days.ago.to_date, end_date: Date.current)]
end
end end
def known_events def known_events
...@@ -132,6 +128,14 @@ module Gitlab ...@@ -132,6 +128,14 @@ module Gitlab
Plan.all_plans Plan.all_plans
end end
def aggregated_metrics_data(start_date)
aggregated_metrics.each_with_object({}) do |aggregation, weekly_data|
next if aggregation[:feature_flag] && Feature.disabled?(aggregation[:feature_flag], default_enabled: false, type: :development)
weekly_data[aggregation[:name]] = calculate_count_for_aggregation(aggregation, start_date: start_date, end_date: Date.current)
end
end
def calculate_count_for_aggregation(aggregation, start_date:, end_date:) def calculate_count_for_aggregation(aggregation, start_date:, end_date:)
case aggregation[:operator] case aggregation[:operator]
when UNION_OF_AGGREGATED_METRICS when UNION_OF_AGGREGATED_METRICS
......
...@@ -33,7 +33,7 @@ RSpec.describe 'aggregated metrics' do ...@@ -33,7 +33,7 @@ RSpec.describe 'aggregated metrics' do
end end
it "has expected structure" do it "has expected structure" do
expect(aggregate.keys).to match_array(%w[name operator events]) expect(aggregate.keys).to include(*%w[name operator events])
end end
it "uses allowed aggregation operators" do it "uses allowed aggregation operators" do
......
...@@ -441,6 +441,28 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s ...@@ -441,6 +441,28 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
expect(aggregated_metrics_data).to eq(results) expect(aggregated_metrics_data).to eq(results)
end end
end end
context 'hidden behind feature flag' do
let(:enabled_feature_flag) { 'test_ff_enabled' }
let(:disabled_feature_flag) { 'test_ff_disabled' }
let(:aggregated_metrics) do
[
# represents stable aggregated metrics that has been fully released
{ name: 'gmau_without_ff', events: %w[event3_slot event5_slot], operator: "ANY" },
# represents new aggregated metric that is under performance testing on gitlab.com
{ name: 'gmau_enabled', events: %w[event4], operator: "ALL", feature_flag: enabled_feature_flag },
# represents aggregated metric that is under development and shouldn't be yet collected even on gitlab.com
{ name: 'gmau_disabled', events: %w[event4], operator: "ALL", feature_flag: disabled_feature_flag }
].map(&:with_indifferent_access)
end
it 'returns the number of unique events for all known events' do
skip_feature_flags_yaml_validation
stub_feature_flags(enabled_feature_flag => true, disabled_feature_flag => false)
expect(aggregated_metrics_data).to eq('gmau_without_ff' => 2, 'gmau_enabled' => 3)
end
end
end end
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