diff options
Diffstat (limited to 'lib/product_analytics')
-rw-r--r-- | lib/product_analytics/collector_app.rb | 40 | ||||
-rw-r--r-- | lib/product_analytics/event_params.rb | 51 |
2 files changed, 91 insertions, 0 deletions
diff --git a/lib/product_analytics/collector_app.rb b/lib/product_analytics/collector_app.rb new file mode 100644 index 00000000000..cf971eef4b6 --- /dev/null +++ b/lib/product_analytics/collector_app.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module ProductAnalytics + class CollectorApp + def call(env) + request = Rack::Request.new(env) + params = request.params + + return not_found unless EventParams.has_required_params?(params) + + # Product analytics feature is behind a flag and is disabled by default. + # We expect limited amount of projects with this feature enabled in first release. + # Since collector has no authentication we temporary prevent recording of events + # for project without the feature enabled. During increase of feature adoption, this + # check will be removed for better performance. + project = Project.find(params['aid'].to_i) + return not_found unless Feature.enabled?(:product_analytics, project, default_enabled: false) + + # Snowplow tracker has own format of events. + # We need to convert them to match the schema of our database. + event_params = EventParams.parse_event_params(params) + + if ProductAnalyticsEvent.create(event_params) + ok + else + not_found + end + rescue ActiveRecord::InvalidForeignKey, ActiveRecord::RecordNotFound + not_found + end + + def ok + [200, {}, []] + end + + def not_found + [404, {}, []] + end + end +end diff --git a/lib/product_analytics/event_params.rb b/lib/product_analytics/event_params.rb new file mode 100644 index 00000000000..d938fe1f594 --- /dev/null +++ b/lib/product_analytics/event_params.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module ProductAnalytics + # Converts params from Snowplow tracker to one compatible with + # GitLab ProductAnalyticsEvent model. The field naming corresponds + # with snowplow event model. Only project_id is GitLab specific. + # + # For information on what each field is you can check next resources: + # * Snowplow tracker protocol: https://github.com/snowplow/snowplow/wiki/snowplow-tracker-protocol + # * Canonical event model: https://github.com/snowplow/snowplow/wiki/canonical-event-model + class EventParams + def self.parse_event_params(params) + { + project_id: params['aid'], + platform: params['p'], + collector_tstamp: Time.zone.now, + event_id: params['eid'], + v_tracker: params['tv'], + v_collector: Gitlab::VERSION, + v_etl: Gitlab::VERSION, + os_timezone: params['tz'], + name_tracker: params['tna'], + br_lang: params['lang'], + doc_charset: params['cs'], + br_features_pdf: Gitlab::Utils.to_boolean(params['f_pdf']), + br_features_flash: Gitlab::Utils.to_boolean(params['f_fla']), + br_features_java: Gitlab::Utils.to_boolean(params['f_java']), + br_features_director: Gitlab::Utils.to_boolean(params['f_dir']), + br_features_quicktime: Gitlab::Utils.to_boolean(params['f_qt']), + br_features_realplayer: Gitlab::Utils.to_boolean(params['f_realp']), + br_features_windowsmedia: Gitlab::Utils.to_boolean(params['f_wma']), + br_features_gears: Gitlab::Utils.to_boolean(params['f_gears']), + br_features_silverlight: Gitlab::Utils.to_boolean(params['f_ag']), + br_colordepth: params['cd'], + br_cookies: Gitlab::Utils.to_boolean(params['cookie']), + dvce_created_tstamp: params['dtm'], + br_viewheight: params['vp'], + domain_sessionidx: params['vid'], + domain_sessionid: params['sid'], + domain_userid: params['duid'], + user_fingerprint: params['fp'], + page_referrer: params['refr'], + page_url: params['url'] + } + end + + def self.has_required_params?(params) + params['aid'].present? && params['eid'].present? + end + end +end |