From 9e2ea140186fc836faeac32b0a59614cb4b396ed Mon Sep 17 00:00:00 2001 From: Niko Belokolodov <nbelokolodov@gitlab.com> Date: Thu, 13 Oct 2022 01:45:03 +0000 Subject: [PATCH] Add context to the first pack of migrated Snowplow events We updated snowplow events taxonomy. This MR adds new context to the initial pack of events (controller based). Also included updated tests --- .../concerns/product_analytics_tracking.rb | 9 ++++++- .../admin/dev_ops_report_controller_spec.rb | 2 +- .../controllers/ee/search_controller_spec.rb | 15 ++++++++--- .../cycle_analytics_controller_spec.rb | 11 +++++--- .../productivity_analytics_controller_spec.rb | 2 +- .../contribution_analytics_controller_spec.rb | 2 +- .../groups/insights_controller_spec.rb | 2 +- .../issues_analytics_controller_spec.rb | 2 +- .../issues_analytics_controller_spec.rb | 2 +- ...merge_request_analytics_controller_spec.rb | 2 +- .../projects/insights_controller_spec.rb | 2 +- .../jira/issues_controller_spec.rb | 2 +- .../devops_adoption_controller_spec.rb | 2 +- .../analytics/code_reviews_controller_spec.rb | 2 +- lib/gitlab/tracking/service_ping_context.rb | 25 +++++++++++++++++++ .../admin/cohorts_controller_spec.rb | 2 +- .../admin/dev_ops_report_controller_spec.rb | 2 +- .../admin/usage_trends_controller_spec.rb | 2 +- .../product_analytics_tracking_spec.rb | 17 +++++++------ .../cycle_analytics_controller_spec.rb | 2 +- .../projects/graphs_controller_spec.rb | 2 +- .../projects/pipelines_controller_spec.rb | 2 +- spec/controllers/search_controller_spec.rb | 2 +- .../tracking/service_ping_context_spec.rb | 19 ++++++++++++++ .../snowplow_event_tracking_examples.rb | 12 ++++++++- 25 files changed, 111 insertions(+), 33 deletions(-) create mode 100644 lib/gitlab/tracking/service_ping_context.rb create mode 100644 spec/lib/gitlab/tracking/service_ping_context_spec.rb diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb index 8e936782e5a60..4f96cc5c89538 100644 --- a/app/controllers/concerns/product_analytics_tracking.rb +++ b/app/controllers/concerns/product_analytics_tracking.rb @@ -29,7 +29,13 @@ def route_events_to(destinations, name, &block) track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll) if destinations.include?(:snowplow) && event_enabled?(name) - Gitlab::Tracking.event(self.class.to_s, name, namespace: tracking_namespace_source, user: current_user) + Gitlab::Tracking.event( + self.class.to_s, + name, + namespace: tracking_namespace_source, + user: current_user, + context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context] + ) end end @@ -49,6 +55,7 @@ def route_custom_events_to(destinations, name, action, label, &block) user: current_user, property: name, label: label, + context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: name).to_context], **optional_arguments ) end diff --git a/ee/spec/controllers/admin/dev_ops_report_controller_spec.rb b/ee/spec/controllers/admin/dev_ops_report_controller_spec.rb index b79f2806fa65c..bfce13199b463 100644 --- a/ee/spec/controllers/admin/dev_ops_report_controller_spec.rb +++ b/ee/spec/controllers/admin/dev_ops_report_controller_spec.rb @@ -43,7 +43,7 @@ ['', 'dev', 'sec', 'ops'].each do |tab| it_behaves_like 'tracks usage event', 'i_analytics_dev_ops_adoption', tab - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: { tab: tab }, format: :html } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/controllers/ee/search_controller_spec.rb b/ee/spec/controllers/ee/search_controller_spec.rb index daa9dbd456b32..acf34eb4eca9d 100644 --- a/ee/spec/controllers/ee/search_controller_spec.rb +++ b/ee/spec/controllers/ee/search_controller_spec.rb @@ -33,9 +33,12 @@ it 'emits all search events' do subject - expect_snowplow_event(category: category, action: 'i_search_total', namespace: namespace, user: user) - expect_snowplow_event(category: category, action: 'i_search_paid', namespace: namespace, user: user) - expect_snowplow_event(category: category, action: 'i_search_advanced', namespace: namespace, user: user) + expect_snowplow_event(category: category, action: 'i_search_total', namespace: namespace, user: user, + context: context('i_search_total')) + expect_snowplow_event(category: category, action: 'i_search_paid', namespace: namespace, user: user, + context: context('i_search_paid')) + expect_snowplow_event(category: category, action: 'i_search_advanced', namespace: namespace, user: user, + context: context('i_search_advanced')) end end @@ -398,4 +401,10 @@ def request end end end + + private + + def context(event) + [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event).to_context.to_json] + end end diff --git a/ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb b/ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb index a69224a1e97ff..8083129689068 100644 --- a/ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb +++ b/ee/spec/controllers/groups/analytics/cycle_analytics_controller_spec.rb @@ -59,8 +59,10 @@ end describe 'tracking events', :snowplow do + let(:event) { 'g_analytics_valuestream' } + it 'tracks redis hll event' do - expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with('g_analytics_valuestream', { values: anything }) + expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event, { values: anything }) get(:show, params: { group_id: group }) end @@ -68,11 +70,14 @@ it 'tracks snowplow event' do get(:show, params: { group_id: group }) + context = Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event).to_context.to_json + expect_snowplow_event( category: 'Groups::Analytics::CycleAnalyticsController', - action: 'g_analytics_valuestream', + action: event, namespace: group, - user: user + user: user, + context: [context] ) end end diff --git a/ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb b/ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb index 43796c72ca3ee..1896547f2e6c2 100644 --- a/ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb +++ b/ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb @@ -74,7 +74,7 @@ let(:target_id) { 'g_analytics_productivity' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: { group_id: group } } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/controllers/groups/contribution_analytics_controller_spec.rb b/ee/spec/controllers/groups/contribution_analytics_controller_spec.rb index ab6635b1ee8ca..b03a40c5a3e6d 100644 --- a/ee/spec/controllers/groups/contribution_analytics_controller_spec.rb +++ b/ee/spec/controllers/groups/contribution_analytics_controller_spec.rb @@ -221,7 +221,7 @@ def create_push_event(author, project) let(:target_id) { 'g_analytics_contribution' } end - it_behaves_like 'Snowplow event tracking', overrides: { project: nil } do + it_behaves_like 'Snowplow event tracking with RedisHLL context', overrides: { project: nil } do let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } let(:category) { described_class.name } let(:action) { 'perform_analytics_usage_action' } diff --git a/ee/spec/controllers/groups/insights_controller_spec.rb b/ee/spec/controllers/groups/insights_controller_spec.rb index ca422c39e6735..d707da29d8f79 100644 --- a/ee/spec/controllers/groups/insights_controller_spec.rb +++ b/ee/spec/controllers/groups/insights_controller_spec.rb @@ -138,7 +138,7 @@ let(:target_id) { 'g_analytics_insights' } end - it_behaves_like 'Snowplow event tracking', overrides: { project: nil } do + it_behaves_like 'Snowplow event tracking with RedisHLL context', overrides: { project: nil } do subject { get :show, params: params.merge(group_id: parent_group.to_param) } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/controllers/groups/issues_analytics_controller_spec.rb b/ee/spec/controllers/groups/issues_analytics_controller_spec.rb index 185711bee6dab..76d7eacf8c04d 100644 --- a/ee/spec/controllers/groups/issues_analytics_controller_spec.rb +++ b/ee/spec/controllers/groups/issues_analytics_controller_spec.rb @@ -34,7 +34,7 @@ let(:target_id) { 'g_analytics_issues' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: { group_id: group.to_param } } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/controllers/projects/analytics/issues_analytics_controller_spec.rb b/ee/spec/controllers/projects/analytics/issues_analytics_controller_spec.rb index f98b1cd999310..a7f3f4661e1ee 100644 --- a/ee/spec/controllers/projects/analytics/issues_analytics_controller_spec.rb +++ b/ee/spec/controllers/projects/analytics/issues_analytics_controller_spec.rb @@ -27,7 +27,7 @@ let(:target_id) { 'p_analytics_issues' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: request_params, format: :html } let(:request_params) { { namespace_id: project.namespace, project_id: project1 } } diff --git a/ee/spec/controllers/projects/analytics/merge_request_analytics_controller_spec.rb b/ee/spec/controllers/projects/analytics/merge_request_analytics_controller_spec.rb index be1af9230636c..3e72f24cef169 100644 --- a/ee/spec/controllers/projects/analytics/merge_request_analytics_controller_spec.rb +++ b/ee/spec/controllers/projects/analytics/merge_request_analytics_controller_spec.rb @@ -28,7 +28,7 @@ let(:target_id) { 'p_analytics_merge_request' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } let(:category) { described_class.name } let(:action) { 'perform_analytics_usage_action' } diff --git a/ee/spec/controllers/projects/insights_controller_spec.rb b/ee/spec/controllers/projects/insights_controller_spec.rb index a8a1b8eae7ecc..f016a231e312d 100644 --- a/ee/spec/controllers/projects/insights_controller_spec.rb +++ b/ee/spec/controllers/projects/insights_controller_spec.rb @@ -107,7 +107,7 @@ let(:target_id) { 'p_analytics_insights' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: params, format: :html } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/controllers/projects/integrations/jira/issues_controller_spec.rb b/ee/spec/controllers/projects/integrations/jira/issues_controller_spec.rb index 1c4f402726b23..eb8b1aa4149d6 100644 --- a/ee/spec/controllers/projects/integrations/jira/issues_controller_spec.rb +++ b/ee/spec/controllers/projects/integrations/jira/issues_controller_spec.rb @@ -66,7 +66,7 @@ get :index, params: { namespace_id: project.namespace, project_id: project } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject(:get_index) { get :index, params: { namespace_id: project.namespace, project_id: project } } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/ee/spec/requests/groups/analytics/devops_adoption_controller_spec.rb b/ee/spec/requests/groups/analytics/devops_adoption_controller_spec.rb index 1858411c2a354..80033d96c0d7c 100644 --- a/ee/spec/requests/groups/analytics/devops_adoption_controller_spec.rb +++ b/ee/spec/requests/groups/analytics/devops_adoption_controller_spec.rb @@ -71,7 +71,7 @@ subject end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } let(:category) { described_class.name } let(:action) { 'perform_analytics_usage_action' } diff --git a/ee/spec/requests/projects/analytics/code_reviews_controller_spec.rb b/ee/spec/requests/projects/analytics/code_reviews_controller_spec.rb index 076018861d09d..1bab44ffc7691 100644 --- a/ee/spec/requests/projects/analytics/code_reviews_controller_spec.rb +++ b/ee/spec/requests/projects/analytics/code_reviews_controller_spec.rb @@ -65,7 +65,7 @@ let(:target_id) { 'p_analytics_code_reviews' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :index, params: request_params, format: :html } let(:request_params) { { namespace_id: project.namespace, project_id: project } } diff --git a/lib/gitlab/tracking/service_ping_context.rb b/lib/gitlab/tracking/service_ping_context.rb new file mode 100644 index 0000000000000..393cd647e7f9c --- /dev/null +++ b/lib/gitlab/tracking/service_ping_context.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Gitlab + module Tracking + class ServicePingContext + SCHEMA_URL = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0' + ALLOWED_SOURCES = %i[redis_hll].freeze + + def initialize(data_source:, event:) + unless ALLOWED_SOURCES.include?(data_source) + raise ArgumentError, "#{data_source} is not acceptable data source for ServicePingContext" + end + + @payload = { + data_source: data_source, + event_name: event + } + end + + def to_context + SnowplowTracker::SelfDescribingJson.new(SCHEMA_URL, @payload) + end + end + end +end diff --git a/spec/controllers/admin/cohorts_controller_spec.rb b/spec/controllers/admin/cohorts_controller_spec.rb index 766073977c6d6..50626a5da912c 100644 --- a/spec/controllers/admin/cohorts_controller_spec.rb +++ b/spec/controllers/admin/cohorts_controller_spec.rb @@ -14,7 +14,7 @@ let(:target_id) { 'i_analytics_cohorts' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :index } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/spec/controllers/admin/dev_ops_report_controller_spec.rb b/spec/controllers/admin/dev_ops_report_controller_spec.rb index 5d7a7e089aa89..52a46b5e99ac4 100644 --- a/spec/controllers/admin/dev_ops_report_controller_spec.rb +++ b/spec/controllers/admin/dev_ops_report_controller_spec.rb @@ -29,7 +29,7 @@ let(:request_params) { { tab: 'devops-score' } } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, format: :html } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/spec/controllers/admin/usage_trends_controller_spec.rb b/spec/controllers/admin/usage_trends_controller_spec.rb index 356f603bf57a0..87cf8988b4e4b 100644 --- a/spec/controllers/admin/usage_trends_controller_spec.rb +++ b/spec/controllers/admin/usage_trends_controller_spec.rb @@ -14,7 +14,7 @@ let(:target_id) { 'i_analytics_instance_statistics' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :index } let(:feature_flag_name) { :route_hll_to_snowplow_phase2 } diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb index 2e734d81ea003..f85b6806f301c 100644 --- a/spec/controllers/concerns/product_analytics_tracking_spec.rb +++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb @@ -55,11 +55,19 @@ def expect_tracking(user: self.user) expect(Gitlab::UsageDataCounters::HLLRedisCounter).to have_received(:track_event) .with('g_analytics_valuestream', values: instance_of(String)) + expect_snowplow_tracking(user) + end + + def expect_snowplow_tracking(user) + context = Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'g_analytics_valuestream') + .to_context.to_json + expect_snowplow_event( category: anything, action: 'g_analytics_valuestream', namespace: group, - user: user + user: user, + context: [context] ) end @@ -160,12 +168,7 @@ def expect_no_tracking get :show, params: { id: 2 } expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event) - expect_snowplow_event( - category: anything, - action: 'g_analytics_valuestream', - namespace: group, - user: nil - ) + expect_snowplow_tracking(nil) end end end diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb index f5dd8abd67b9f..034e6104f99a5 100644 --- a/spec/controllers/projects/cycle_analytics_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb @@ -31,7 +31,7 @@ let(:target_id) { 'p_analytics_valuestream' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: request_params, format: :html } let(:request_params) { { namespace_id: project.namespace, project_id: project } } diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index 9227c7dd70a98..3dfc22927cfd4 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -90,7 +90,7 @@ let(:target_id) { 'p_analytics_repo' } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject do sign_in(user) get :charts, params: request_params, format: :html diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index b9acaf658926e..6e2de0c4d57e5 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -859,7 +859,7 @@ def get_stage(name, params = {}) let(:target_id) { ['p_analytics_pipelines', tab[:event]] } end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :charts, params: request_params, format: :html } let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } } diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 4131bd148dad2..7ab66b04a6e53 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -218,7 +218,7 @@ end end - it_behaves_like 'Snowplow event tracking' do + it_behaves_like 'Snowplow event tracking with RedisHLL context' do subject { get :show, params: { group_id: namespace.id, scope: 'blobs', search: 'term' } } let(:project) { nil } diff --git a/spec/lib/gitlab/tracking/service_ping_context_spec.rb b/spec/lib/gitlab/tracking/service_ping_context_spec.rb new file mode 100644 index 0000000000000..d70dfaa4e0b51 --- /dev/null +++ b/spec/lib/gitlab/tracking/service_ping_context_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Tracking::ServicePingContext do + describe '#init' do + it 'does not accept unsupported data sources' do + expect { described_class.new(data_source: :random, event: 'event a') }.to raise_error(ArgumentError) + end + end + + describe '#to_context' do + let(:subject) { described_class.new(data_source: :redis_hll, event: 'sample_event') } + + it 'contains event_name' do + expect(subject.to_context.to_json.dig(:data, :event_name)).to eq('sample_event') + end + end +end diff --git a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb index 4af3c0cc6cc2e..6749ebd471f1d 100644 --- a/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb +++ b/spec/support/shared_examples/controllers/snowplow_event_tracking_examples.rb @@ -32,7 +32,8 @@ user: try(:user), project: try(:project), label: try(:label), - property: try(:property) + property: try(:property), + context: try(:context) }.merge(overrides).compact.merge(extra) subject @@ -40,3 +41,12 @@ expect_snowplow_event(**params) end end + +RSpec.shared_examples 'Snowplow event tracking with RedisHLL context' do |overrides: {}| + it_behaves_like 'Snowplow event tracking', overrides: overrides do + let(:context) do + event = try(:property) || action + [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event).to_context.to_json] + end + end +end -- GitLab