diff --git a/Gemfile b/Gemfile index f8438271a7b00fe5b78f2a88b1113dc7c22fe641..dbf4fed230be13b5c65f49c47bd4e1f781fc4747 100644 --- a/Gemfile +++ b/Gemfile @@ -303,6 +303,9 @@ gem 'peek-pg', '~> 1.3.0', group: :postgres gem 'peek-rblineprof', '~> 0.2.0' gem 'peek-redis', '~> 1.2.0' +# Snowplow events tracking +gem 'snowplow-tracker', '~> 0.6.1' + # Metrics group :metrics do gem 'method_source', '~> 0.8', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 92400bc11693ba22a623898287de9d3e3c472bcf..5bc30a2b472aecf3952cd506f972cb4905d39d70 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -144,6 +144,7 @@ GEM concurrent-ruby-ext (1.1.3) concurrent-ruby (= 1.1.3) connection_pool (2.2.2) + contracts (0.11.0) crack (0.4.3) safe_yaml (~> 1.0.0) crass (1.0.4) @@ -873,6 +874,8 @@ GEM simplecov-html (~> 0.10.0) simplecov-html (0.10.0) slack-notifier (1.5.1) + snowplow-tracker (0.6.1) + contracts (~> 0.7, <= 0.11) spring (2.0.2) activesupport (>= 4.2) spring-commands-rspec (1.0.4) @@ -1191,6 +1194,7 @@ DEPENDENCIES simple_po_parser (~> 1.1.2) simplecov (~> 0.14.0) slack-notifier (~> 1.5.1) + snowplow-tracker (~> 0.6.1) spring (~> 2.0.0) spring-commands-rspec (~> 1.0.4) sprockets (~> 3.7.0) diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml index af76bace577e0868f8ac469e42983f17f5700461..40a80429afa08711303ab26bddc868d36db639bc 100644 --- a/config/dependency_decisions.yml +++ b/config/dependency_decisions.yml @@ -599,3 +599,10 @@ :why: https://github.com/apache/incubator-echarts/blob/master/LICENSE :versions: [] :when: 2018-12-07 20:46:12.421256000 Z +- - :license + - contracts + - BSD + - :who: Jarka Košanová + :why: https://github.com/egonSchiele/contracts.ruby/blob/master/LICENSE + :versions: [] + :when: 2019-04-01 11:29:39.361015000 Z diff --git a/ee/app/views/layouts/_snowplow.html.haml b/ee/app/views/layouts/_snowplow.html.haml index 456f3c3826983682bbfd790d47db3b717ce8a047..5f29b8856c1b15bd1a873d9ede21066fce077364 100644 --- a/ee/app/views/layouts/_snowplow.html.haml +++ b/ee/app/views/layouts/_snowplow.html.haml @@ -5,7 +5,7 @@ };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","#{asset_url('snowplow/sp.js')}","snowplow")); - window.snowplow('newTracker', 'cf', '#{Gitlab::CurrentSettings.snowplow_collector_uri}', { + window.snowplow('newTracker', #{Gitlab::SnowplowTracker::NAMESPACE}, '#{Gitlab::CurrentSettings.snowplow_collector_uri}', { appId: '#{Gitlab::CurrentSettings.snowplow_site_id}', cookieDomain: '#{Gitlab::CurrentSettings.snowplow_cookie_domain}', userFingerprint: false, diff --git a/ee/lib/gitlab/snowplow_tracker.rb b/ee/lib/gitlab/snowplow_tracker.rb new file mode 100644 index 0000000000000000000000000000000000000000..9db63ddf248a5ddbc412e33709dcacd6d27d119a --- /dev/null +++ b/ee/lib/gitlab/snowplow_tracker.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'snowplow-tracker' + +module Gitlab + module SnowplowTracker + NAMESPACE = 'cf' + + class << self + def track_event(category, action, label: nil, property: nil, value: nil, context: nil) + return unless enabled? + + tracker.track_struct_event(category, action, label, property, value, context, Time.now.to_i) + end + + private + + def tracker + return unless enabled? + + @tracker ||= ::SnowplowTracker::Tracker.new(emitter, subject, NAMESPACE, Gitlab::CurrentSettings.snowplow_site_id) + end + + def subject + ::SnowplowTracker::Subject.new + end + + def emitter + ::SnowplowTracker::Emitter.new(Gitlab::CurrentSettings.snowplow_collector_uri) + end + + def enabled? + Gitlab::CurrentSettings.snowplow_enabled? + end + end + end +end diff --git a/ee/spec/lib/gitlab/snowplow_tracker_spec.rb b/ee/spec/lib/gitlab/snowplow_tracker_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b298f7aed01f48bcca4592e3e7c04c0d8e041cc2 --- /dev/null +++ b/ee/spec/lib/gitlab/snowplow_tracker_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Gitlab::SnowplowTracker do + let(:timestamp) { Time.utc(2017, 3, 22) } + + around do |example| + Timecop.freeze(timestamp) { example.run } + end + + subject { described_class.track_event('category', 'action', property: 'what', value: 'doit') } + + context '.track_event' do + context 'when Snowplow tracker is disabled' do + it 'does not track the event' do + expect(SnowplowTracker::Tracker).not_to receive(:new) + + subject + end + end + + context 'when Snowplow tracker is enabled' do + it 'tracks the event' do + stub_application_setting(snowplow_enabled: true) + stub_application_setting(snowplow_site_id: 'awesome gitlab') + stub_application_setting(snowplow_collector_uri: 'url.com') + tracker = double + + expect(::SnowplowTracker::Tracker).to receive(:new) + .with( + an_instance_of(::SnowplowTracker::Emitter), + an_instance_of(::SnowplowTracker::Subject), + 'cf', 'awesome gitlab' + ).and_return(tracker) + expect(tracker).to receive(:track_struct_event) + .with('category', 'action', nil, 'what', 'doit', nil, timestamp.to_i) + + subject + end + end + end +end