Skip to content
Snippets Groups Projects
Commit 27b6e1ff authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Merge branch '342068-global-search-apdex-to-prometheus' into 'master'

Expose global_search_apdex as a prometheus metric

See merge request !95182
parents fd8c20fa 560a9bf9
No related branches found
No related tags found
1 merge request!95182Expose global_search_apdex as a prometheus metric
Pipeline #627525755 passed
......@@ -57,6 +57,13 @@ def show
@search_highlight = @search_service.search_highlight
end
Gitlab::Metrics::GlobalSearchSlis.record_apdex(
elapsed: @global_search_duration_s,
search_type: @search_type,
search_level: @search_level,
search_scope: @scope
)
increment_search_counters
end
......
---
name: global_search_custom_slis
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95182
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372107
milestone: '15.4'
type: development
group: group::application performance
default_enabled: false
......@@ -40,6 +40,7 @@
if Gitlab::Runtime.puma?
Gitlab::Metrics::RequestsRackMiddleware.initialize_metrics
Gitlab::Metrics::GlobalSearchSlis.initialize_slis!
end
GC::Profiler.enable
......
......@@ -65,6 +65,13 @@ def search(additional_params = {})
set_global_search_log_information
Gitlab::Metrics::GlobalSearchSlis.record_apdex(
elapsed: @search_duration_s,
search_type: search_type,
search_level: search_service.level,
search_scope: search_scope
)
Gitlab::UsageDataCounters::SearchCounter.count(:all_searches)
paginate(@results)
......
# frozen_string_literal: true
module Gitlab
module Metrics
module GlobalSearchSlis
class << self
# The following targets are the 99.95th percentile of code searches
# gathered on 24-08-2022
# from https://log.gprd.gitlab.net/goto/0c89cd80-23af-11ed-8656-f5f2137823ba (internal only)
BASIC_CONTENT_TARGET_S = 7.031
BASIC_CODE_TARGET_S = 21.903
ADVANCED_CONTENT_TARGET_S = 4.865
ADVANCED_CODE_TARGET_S = 13.546
def initialize_slis!
return unless Feature.enabled?(:global_search_custom_slis)
Gitlab::Metrics::Sli::Apdex.initialize_sli(:global_search, possible_labels)
end
def record_apdex(elapsed:, search_type:, search_level:, search_scope:)
return unless Feature.enabled?(:global_search_custom_slis)
Gitlab::Metrics::Sli::Apdex[:global_search].increment(
labels: labels(search_type: search_type, search_level: search_level, search_scope: search_scope),
success: elapsed < duration_target(search_type, search_scope)
)
end
private
def duration_target(search_type, search_scope)
if search_type == 'basic' && content_search?(search_scope)
BASIC_CONTENT_TARGET_S
elsif search_type == 'basic' && code_search?(search_scope)
BASIC_CODE_TARGET_S
elsif search_type == 'advanced' && content_search?(search_scope)
ADVANCED_CONTENT_TARGET_S
elsif search_type == 'advanced' && code_search?(search_scope)
ADVANCED_CODE_TARGET_S
end
end
def search_types
%w[basic advanced]
end
def search_levels
%w[project group global]
end
def search_scopes
Gitlab::Search::AbuseDetection::ALLOWED_SCOPES
end
def endpoint_ids
['SearchController#show', 'GET /api/:version/search', 'GET /api/:version/projects/:id/(-/)search',
'GET /api/:version/groups/:id/(-/)search']
end
def possible_labels
search_types.flat_map do |search_type|
search_levels.flat_map do |search_level|
search_scopes.flat_map do |search_scope|
endpoint_ids.flat_map do |endpoint_id|
{
search_type: search_type,
search_level: search_level,
search_scope: search_scope,
endpoint_id: endpoint_id
}
end
end
end
end
end
def labels(search_type:, search_level:, search_scope:)
{
search_type: search_type,
search_level: search_level,
search_scope: search_scope,
endpoint_id: endpoint_id
}
end
def endpoint_id
::Gitlab::ApplicationContext.current_context_attribute(:caller_id)
end
def code_search?(search_scope)
search_scope == 'blobs'
end
def content_search?(search_scope)
!code_search?(search_scope)
end
end
end
end
end
......@@ -270,6 +270,17 @@ def request
get(:show, params: { search: 'foo@bar.com', scope: 'users' })
end
end
it 'increments the custom search sli apdex' do
expect(Gitlab::Metrics::GlobalSearchSlis).to receive(:record_apdex).with(
elapsed: a_kind_of(Numeric),
search_scope: 'issues',
search_type: 'basic',
search_level: 'global'
)
get :show, params: { scope: 'issues', search: 'hello world' }
end
end
describe 'GET #count', :aggregate_failures do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Metrics::GlobalSearchSlis do
using RSpec::Parameterized::TableSyntax
before do
stub_feature_flags(global_search_custom_slis: feature_flag_enabled)
end
describe '#initialize_slis!' do
context 'when global_search_custom_slis feature flag is enabled' do
let(:feature_flag_enabled) { true }
it 'initializes Apdex SLI for global_search' do
expect(Gitlab::Metrics::Sli::Apdex).to receive(:initialize_sli).with(
:global_search,
a_kind_of(Array)
)
described_class.initialize_slis!
end
end
context 'when global_search_custom_slis feature flag is disabled' do
let(:feature_flag_enabled) { false }
it 'does not initialzie the Apdex SLI for global_search' do
expect(Gitlab::Metrics::Sli::Apdex).not_to receive(:initialize_sli)
described_class.initialize_slis!
end
end
end
describe '#record_apdex' do
context 'when global_search_custom_slis feature flag is enabled' do
let(:feature_flag_enabled) { true }
where(:search_type, :code_search, :duration_target) do
'basic' | false | 7.031
'basic' | true | 21.903
'advanced' | false | 4.865
'advanced' | true | 13.546
end
with_them do
before do
allow(::Gitlab::ApplicationContext).to receive(:current_context_attribute).with(:caller_id).and_return('end')
end
let(:search_scope) { code_search ? 'blobs' : 'issues' }
it 'increments the global_search SLI as a success if the elapsed time is within the target' do
duration = duration_target - 0.1
expect(Gitlab::Metrics::Sli::Apdex[:global_search]).to receive(:increment).with(
labels: {
search_type: search_type,
search_level: 'global',
search_scope: search_scope,
endpoint_id: 'end'
},
success: true
)
described_class.record_apdex(
elapsed: duration,
search_type: search_type,
search_level: 'global',
search_scope: search_scope
)
end
it 'increments the global_search SLI as a failure if the elapsed time is not within the target' do
duration = duration_target + 0.1
expect(Gitlab::Metrics::Sli::Apdex[:global_search]).to receive(:increment).with(
labels: {
search_type: search_type,
search_level: 'global',
search_scope: search_scope,
endpoint_id: 'end'
},
success: false
)
described_class.record_apdex(
elapsed: duration,
search_type: search_type,
search_level: 'global',
search_scope: search_scope
)
end
end
end
context 'when global_search_custom_slis feature flag is disabled' do
let(:feature_flag_enabled) { false }
it 'does not call increment on the apdex SLI' do
expect(Gitlab::Metrics::Sli::Apdex[:global_search]).not_to receive(:increment)
described_class.record_apdex(
elapsed: 1,
search_type: 'basic',
search_level: 'global',
search_scope: 'issues'
)
end
end
end
end
......@@ -351,6 +351,17 @@
end
end
it 'increments the custom search sli apdex' do
expect(Gitlab::Metrics::GlobalSearchSlis).to receive(:record_apdex).with(
elapsed: a_kind_of(Numeric),
search_scope: 'issues',
search_type: 'basic',
search_level: 'global'
)
get api(endpoint, user), params: { scope: 'issues', search: 'john doe' }
end
it 'sets global search information for logging' do
expect(Gitlab::Instrumentation::GlobalSearchApi).to receive(:set_information).with(
type: 'basic',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment