Commit ad75ad88 authored by Mark Chao's avatar Mark Chao

Merge branch '238116-redis-hll-search-analytics' into 'master'

Add search analytics event

Closes #238116

See merge request gitlab-org/gitlab!40134
parents 33535063 47e5d947
......@@ -4,12 +4,15 @@ class SearchController < ApplicationController
include ControllerWithCrossProjectAccessCheck
include SearchHelper
include RendersCommits
include RedisTracking
SCOPE_PRELOAD_METHOD = {
projects: :with_web_entity_associations,
issues: :with_web_entity_associations
}.freeze
track_redis_hll_event :show, name: 'i_search_total', feature: :search_track_unique_users
around_action :allow_gitaly_ref_name_caching
skip_before_action :authenticate_user!
......@@ -126,3 +129,5 @@ class SearchController < ApplicationController
payload[:metadata]['meta.search.scope'] = params[:scope]
end
end
SearchController.prepend_if_ee('EE::SearchController')
---
title: Add the unique search visits data to the usage ping
merge_request: 40134
author:
type: changed
---
name: search_track_unique_users
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40134
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/240906
group: group::global search
type: development
default_enabled: false
# frozen_string_literal: true
module EE
module SearchController
extend ActiveSupport::Concern
prepended do
before_action :track_advanced_search, only: :show, if: -> { request.format.html? && request.headers['DNT'] != '1' }
end
private
def track_advanced_search
# track unique users of advanced global search
track_unique_redis_hll_event("i_search_advanced", :search_track_unique_users) if search_service.use_elasticsearch?
# track unique users who search against paid groups/projects
track_unique_redis_hll_event("i_search_paid", :search_track_unique_users) if (search_service.project || search_service.group)&.feature_available?(:elastic_search)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe SearchController do
let_it_be(:user) { create(:user) }
before do
sign_in(user)
end
describe 'GET #show' do
context 'unique users tracking', :elastic do
before do
stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true)
allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
end
context 'i_search_advanced' do
it_behaves_like 'tracking unique hll events', :show do
let(:request_params) { { scope: 'projects', search: 'term' } }
let(:target_id) { 'i_search_advanced' }
end
end
context 'i_search_paid' do
let(:group) { create(:group) }
before do
allow(group).to receive(:feature_available?).with(:elastic_search).and_return(true)
end
it_behaves_like 'tracking unique hll events', :show do
let(:request_params) { { group_id: group.id, scope: 'blobs', search: 'term' } }
let(:target_id) { 'i_search_paid' }
end
end
end
end
end
......@@ -38,6 +38,7 @@ module Gitlab
.merge(usage_activity_by_stage(:usage_activity_by_stage_monthly, last_28_days_time_period))
.merge(analytics_unique_visits_data)
.merge(compliance_unique_visits_data)
.merge(search_unique_visits_data)
end
end
......@@ -608,6 +609,18 @@ module Gitlab
{ compliance_unique_visits: results }
end
def search_unique_visits_data
events = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('search')
results = events.each_with_object({}) do |event, hash|
hash[event] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: event, start_date: 7.days.ago.to_date, end_date: Date.current) }
end
results['search_unique_visits_for_any_target_weekly'] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: 7.days.ago.to_date, end_date: Date.current) }
results['search_unique_visits_for_any_target_monthly'] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: 4.weeks.ago.to_date, end_date: Date.current) }
{ search_unique_visits: results }
end
def action_monthly_active_users(time_period)
counter = Gitlab::UsageDataCounters::TrackUniqueEvents
......
......@@ -84,3 +84,15 @@
redis_slot: edit
expiry: 29
aggregation: daily
- name: i_search_total
category: search
redis_slot: search
aggregation: weekly
- name: i_search_advanced
category: search
redis_slot: search
aggregation: weekly
- name: i_search_paid
category: search
redis_slot: search
aggregation: weekly
......@@ -149,6 +149,11 @@ RSpec.describe SearchController do
expect(assigns[:search_objects].first).to eq note
end
it_behaves_like 'tracking unique hll events', :show do
let(:request_params) { { scope: 'projects', search: 'term' } }
let(:target_id) { 'i_search_total' }
end
context 'on restricted projects' do
context 'when signed out' do
before do
......
......@@ -1020,6 +1020,32 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end
end
describe '.search_unique_visits_data' do
subject { described_class.search_unique_visits_data }
before do
described_class.clear_memoization(:unique_visit_service)
events = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('search')
events.each do |event|
allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: event, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(123)
end
allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(543)
allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 4.weeks.ago.to_date, end_date: Date.current).and_return(987)
end
it 'returns the number of unique visits to pages with search features' do
expect(subject).to eq({
search_unique_visits: {
'i_search_total' => 123,
'i_search_advanced' => 123,
'i_search_paid' => 123,
'search_unique_visits_for_any_target_weekly' => 543,
'search_unique_visits_for_any_target_monthly' => 987
}
})
end
end
describe '.service_desk_counts' do
subject { described_class.send(:service_desk_counts) }
......
# frozen_string_literal: true
RSpec.shared_examples 'tracking unique hll events' do |method|
it 'tracks unique event if the format is HTML' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(instance_of(String), target_id)
get method, params: request_params, format: :html
end
it 'tracks unique event if DNT is not enabled' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(instance_of(String), target_id)
request.headers['DNT'] = '0'
get method, params: request_params, format: :html
end
it 'does not track unique event if DNT is enabled' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with(instance_of(String), target_id)
request.headers['DNT'] = '1'
get method, params: request_params, format: :html
end
it 'does not track unique event if the format is JSON' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with(instance_of(String), target_id)
get method, params: request_params, format: :json
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