Commit ee9a1129 authored by Dmytro Zaporozhets (DZ)'s avatar Dmytro Zaporozhets (DZ)

Merge branch '254832-merge-productanalytics-tracker-event-into-gitlab-tracking-event' into 'master'

Extract Snowplow tracker into separate class [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!45918
parents e88e96e6 4cefbc2f
# frozen_string_literal: true # frozen_string_literal: true
require 'snowplow-tracker'
module Gitlab module Gitlab
module Tracking module Tracking
SNOWPLOW_NAMESPACE = 'gl' SNOWPLOW_NAMESPACE = 'gl'
...@@ -27,16 +25,11 @@ module Gitlab ...@@ -27,16 +25,11 @@ module Gitlab
end end
def event(category, action, label: nil, property: nil, value: nil, context: nil) def event(category, action, label: nil, property: nil, value: nil, context: nil)
return unless enabled? snowplow.event(category, action, label: label, property: property, value: value, context: context)
snowplow.track_struct_event(category, action, label, property, value, context, (Time.now.to_f * 1000).to_i)
end end
def self_describing_event(schema_url, event_data_json, context: nil) def self_describing_event(schema_url, event_data_json, context: nil)
return unless enabled? snowplow.self_describing_event(schema_url, event_data_json, context: context)
event_json = SnowplowTracker::SelfDescribingJson.new(schema_url, event_data_json)
snowplow.track_self_describing_event(event_json, context, (Time.now.to_f * 1000).to_i)
end end
def snowplow_options(group) def snowplow_options(group)
...@@ -54,19 +47,7 @@ module Gitlab ...@@ -54,19 +47,7 @@ module Gitlab
private private
def snowplow def snowplow
@snowplow ||= SnowplowTracker::Tracker.new( @snowplow ||= Gitlab::Tracking::Destinations::Snowplow.new
emitter,
SnowplowTracker::Subject.new,
SNOWPLOW_NAMESPACE,
Gitlab::CurrentSettings.snowplow_app_id
)
end
def emitter
SnowplowTracker::AsyncEmitter.new(
Gitlab::CurrentSettings.snowplow_collector_hostname,
protocol: 'https'
)
end end
end end
end end
......
# frozen_string_literal: true
module Gitlab
module Tracking
module Destinations
class Base
def event(category, action, label: nil, property: nil, value: nil, context: nil)
raise NotImplementedError, "#{self} does not implement #{__method__}"
end
end
end
end
end
# frozen_string_literal: true
require 'snowplow-tracker'
module Gitlab
module Tracking
module Destinations
class Snowplow < Base
extend ::Gitlab::Utils::Override
override :event
def 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_f * 1000).to_i)
end
def self_describing_event(schema_url, event_data_json, context: nil)
return unless enabled?
event_json = SnowplowTracker::SelfDescribingJson.new(schema_url, event_data_json)
tracker.track_self_describing_event(event_json, context, (Time.now.to_f * 1000).to_i)
end
private
def enabled?
Gitlab::CurrentSettings.snowplow_enabled?
end
def tracker
@tracker ||= SnowplowTracker::Tracker.new(
emitter,
SnowplowTracker::Subject.new,
Gitlab::Tracking::SNOWPLOW_NAMESPACE,
Gitlab::CurrentSettings.snowplow_app_id
)
end
def emitter
SnowplowTracker::AsyncEmitter.new(
Gitlab::CurrentSettings.snowplow_collector_hostname,
protocol: 'https'
)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Tracking::Destinations::Snowplow do
let(:emitter) { SnowplowTracker::Emitter.new('localhost', buffer_size: 1) }
let(:tracker) { SnowplowTracker::Tracker.new(emitter, SnowplowTracker::Subject.new, 'namespace', 'app_id') }
before do
stub_application_setting(snowplow_collector_hostname: 'gitfoo.com')
stub_application_setting(snowplow_app_id: '_abc123_')
end
around do |example|
freeze_time { example.run }
end
context 'when snowplow is enabled' do
before do
stub_application_setting(snowplow_enabled: true)
expect(SnowplowTracker::AsyncEmitter)
.to receive(:new)
.with('gitfoo.com', { protocol: 'https' })
.and_return(emitter)
expect(SnowplowTracker::Tracker)
.to receive(:new)
.with(emitter, an_instance_of(SnowplowTracker::Subject), Gitlab::Tracking::SNOWPLOW_NAMESPACE, '_abc123_')
.and_return(tracker)
end
describe '#event' do
it 'sends event to tracker' do
allow(tracker).to receive(:track_struct_event).and_call_original
subject.event('category', 'action', label: 'label', property: 'property', value: 1.5)
expect(tracker)
.to have_received(:track_struct_event)
.with('category', 'action', 'label', 'property', 1.5, nil, (Time.now.to_f * 1000).to_i)
end
end
describe '#self_describing_event' do
it 'sends event to tracker' do
allow(tracker).to receive(:track_self_describing_event).and_call_original
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
expect(tracker).to have_received(:track_self_describing_event) do |event, context, timestamp|
expect(event.to_json[:schema]).to eq('iglu:com.gitlab/foo/jsonschema/1-0-0')
expect(event.to_json[:data]).to eq(foo: 'bar')
expect(context).to eq(nil)
expect(timestamp).to eq((Time.now.to_f * 1000).to_i)
end
end
end
end
context 'when snowplow is not enabled' do
describe '#event' do
it 'does not send event to tracker' do
expect_any_instance_of(SnowplowTracker::Tracker).not_to receive(:track_struct_event)
subject.event('category', 'action', label: 'label', property: 'property', value: 1.5)
end
end
describe '#self_describing_event' do
it 'does not send event to tracker' do
expect_any_instance_of(SnowplowTracker::Tracker).not_to receive(:track_self_describing_event)
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
end
end
end
end
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Tracking do RSpec.describe Gitlab::Tracking do
let(:timestamp) { Time.utc(2017, 3, 22) }
before do before do
stub_application_setting(snowplow_enabled: true) stub_application_setting(snowplow_enabled: true)
stub_application_setting(snowplow_collector_hostname: 'gitfoo.com') stub_application_setting(snowplow_collector_hostname: 'gitfoo.com')
stub_application_setting(snowplow_cookie_domain: '.gitfoo.com') stub_application_setting(snowplow_cookie_domain: '.gitfoo.com')
stub_application_setting(snowplow_app_id: '_abc123_') stub_application_setting(snowplow_app_id: '_abc123_')
described_class.instance_variable_set("@snowplow", nil)
end end
describe '.snowplow_options' do describe '.snowplow_options' do
...@@ -35,99 +35,23 @@ RSpec.describe Gitlab::Tracking do ...@@ -35,99 +35,23 @@ RSpec.describe Gitlab::Tracking do
end end
end end
describe 'tracking events' do describe '.event' do
shared_examples 'events not tracked' do it 'delegates to snowplow destination' do
it 'does not track events' do expect_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
stub_application_setting(snowplow_enabled: false) .to receive(:event)
expect(SnowplowTracker::AsyncEmitter).not_to receive(:new) .with('category', 'action', label: 'label', property: 'property', value: 1.5, context: nil)
expect(SnowplowTracker::Tracker).not_to receive(:new)
track_event
end
end
around do |example|
travel_to(timestamp) { example.run }
end
before do
described_class.instance_variable_set("@snowplow", nil)
end
let(:tracker) { double }
def receive_events
expect(SnowplowTracker::AsyncEmitter).to receive(:new).with(
'gitfoo.com', { protocol: 'https' }
).and_return('_emitter_')
expect(SnowplowTracker::Tracker).to receive(:new).with( described_class.event('category', 'action', label: 'label', property: 'property', value: 1.5)
'_emitter_',
an_instance_of(SnowplowTracker::Subject),
'gl',
'_abc123_'
).and_return(tracker)
end end
end
describe '.event' do describe '.self_describing_event' do
let(:track_event) do it 'delegates to snowplow destination' do
described_class.event('category', 'action', expect_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
label: '_label_', .to receive(:self_describing_event)
property: '_property_', .with('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' }, context: nil)
value: '_value_',
context: nil
)
end
it_behaves_like 'events not tracked'
it 'can track events' do
receive_events
expect(tracker).to receive(:track_struct_event).with(
'category',
'action',
'_label_',
'_property_',
'_value_',
nil,
(timestamp.to_f * 1000).to_i
)
track_event
end
end
describe '.self_describing_event' do
let(:track_event) do
described_class.self_describing_event('iglu:com.gitlab/example/jsonschema/1-0-2',
{
foo: 'bar',
foo_count: 42
},
context: nil
)
end
it_behaves_like 'events not tracked'
it 'can track self describing events' do
receive_events
expect(SnowplowTracker::SelfDescribingJson).to receive(:new).with(
'iglu:com.gitlab/example/jsonschema/1-0-2',
{
foo: 'bar',
foo_count: 42
}
).and_return('_event_json_')
expect(tracker).to receive(:track_self_describing_event).with(
'_event_json_',
nil,
(timestamp.to_f * 1000).to_i
)
track_event described_class.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
end
end end
end end
end end
...@@ -7,7 +7,7 @@ RSpec.configure do |config| ...@@ -7,7 +7,7 @@ RSpec.configure do |config|
# WebMock is set up to allow requests to `localhost` # WebMock is set up to allow requests to `localhost`
host = 'localhost' host = 'localhost'
allow(Gitlab::Tracking) allow_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
.to receive(:emitter) .to receive(:emitter)
.and_return(SnowplowTracker::Emitter.new(host, buffer_size: buffer_size)) .and_return(SnowplowTracker::Emitter.new(host, buffer_size: buffer_size))
...@@ -17,6 +17,6 @@ RSpec.configure do |config| ...@@ -17,6 +17,6 @@ RSpec.configure do |config|
end end
config.after(:each, :snowplow) do config.after(:each, :snowplow) do
Gitlab::Tracking.send(:snowplow).flush Gitlab::Tracking.send(:snowplow).send(:tracker).flush
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