diff options
Diffstat (limited to 'lib/gitlab/metrics')
-rw-r--r-- | lib/gitlab/metrics/background_transaction.rb | 17 | ||||
-rw-r--r-- | lib/gitlab/metrics/methods.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/metrics/rails_slis.rb | 32 | ||||
-rw-r--r-- | lib/gitlab/metrics/requests_rack_middleware.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/metrics/samplers/action_cable_sampler.rb | 23 | ||||
-rw-r--r-- | lib/gitlab/metrics/subscribers/action_view.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/metrics/subscribers/external_http.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/metrics/subscribers/rails_cache.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/metrics/transaction.rb | 25 | ||||
-rw-r--r-- | lib/gitlab/metrics/web_transaction.rb | 25 |
10 files changed, 81 insertions, 73 deletions
diff --git a/lib/gitlab/metrics/background_transaction.rb b/lib/gitlab/metrics/background_transaction.rb index a1fabe75a97..54095461dd4 100644 --- a/lib/gitlab/metrics/background_transaction.rb +++ b/lib/gitlab/metrics/background_transaction.rb @@ -2,14 +2,17 @@ module Gitlab module Metrics + # Exclusive transaction-type metrics for background jobs (Sidekiq). One + # instance of this class is created for each job going through the Sidekiq + # metric middleware. Any metrics dispatched with this instance include + # metadata such as endpoint_id, queue, and feature category. class BackgroundTransaction < Transaction - # Separate web transaction instance and background transaction instance - BACKGROUND_THREAD_KEY = :_gitlab_metrics_background_transaction - BACKGROUND_BASE_LABEL_KEYS = %i(endpoint_id feature_category).freeze + THREAD_KEY = :_gitlab_metrics_background_transaction + BASE_LABEL_KEYS = %i(queue endpoint_id feature_category).freeze class << self def current - Thread.current[BACKGROUND_THREAD_KEY] + Thread.current[THREAD_KEY] end def prometheus_metric(name, type, &block) @@ -19,17 +22,17 @@ module Gitlab evaluate(&block) # always filter sensitive labels and merge with base ones - label_keys BACKGROUND_BASE_LABEL_KEYS | (label_keys - ::Gitlab::Metrics::Transaction::FILTERED_LABEL_KEYS) + label_keys BASE_LABEL_KEYS | (label_keys - ::Gitlab::Metrics::Transaction::FILTERED_LABEL_KEYS) end end end def run - Thread.current[BACKGROUND_THREAD_KEY] = self + Thread.current[THREAD_KEY] = self yield ensure - Thread.current[BACKGROUND_THREAD_KEY] = nil + Thread.current[THREAD_KEY] = nil end def labels diff --git a/lib/gitlab/metrics/methods.rb b/lib/gitlab/metrics/methods.rb index 8ddd76ad7ae..dc9a7ed1312 100644 --- a/lib/gitlab/metrics/methods.rb +++ b/lib/gitlab/metrics/methods.rb @@ -13,8 +13,12 @@ module Gitlab end class_methods do - def reload_metric!(name) - @@_metrics_provider_cache.delete(name) + def reload_metric!(name = nil) + if name.nil? + @@_metrics_provider_cache = {} + else + @@_metrics_provider_cache.delete(name) + end end private diff --git a/lib/gitlab/metrics/rails_slis.rb b/lib/gitlab/metrics/rails_slis.rb index 69e0c1e9fde..8c40c0ad441 100644 --- a/lib/gitlab/metrics/rails_slis.rb +++ b/lib/gitlab/metrics/rails_slis.rb @@ -4,23 +4,32 @@ module Gitlab module Metrics module RailsSlis class << self - def request_apdex_counters_enabled? - Feature.enabled?(:request_apdex_counters) - end - def initialize_request_slis_if_needed! - return unless request_apdex_counters_enabled? - return if Gitlab::Metrics::Sli.initialized?(:rails_request_apdex) - - Gitlab::Metrics::Sli.initialize_sli(:rails_request_apdex, possible_request_labels) + Gitlab::Metrics::Sli.initialize_sli(:rails_request_apdex, possible_request_labels) unless Gitlab::Metrics::Sli.initialized?(:rails_request_apdex) + Gitlab::Metrics::Sli.initialize_sli(:graphql_query_apdex, possible_graphql_query_labels) unless Gitlab::Metrics::Sli.initialized?(:graphql_query_apdex) end def request_apdex Gitlab::Metrics::Sli[:rails_request_apdex] end + def graphql_query_apdex + Gitlab::Metrics::Sli[:graphql_query_apdex] + end + private + def possible_graphql_query_labels + ::Gitlab::Graphql::KnownOperations.default.operations.map do |op| + { + endpoint_id: op.to_caller_id, + # We'll be able to correlate feature_category with https://gitlab.com/gitlab-org/gitlab/-/issues/328535 + feature_category: nil, + query_urgency: op.query_urgency.name + } + end + end + def possible_request_labels possible_controller_labels + possible_api_labels end @@ -30,10 +39,12 @@ module Gitlab endpoint_id = API::Base.endpoint_id_for_route(route) route_class = route.app.options[:for] feature_category = route_class.feature_category_for_app(route.app) + request_urgency = route_class.urgency_for_app(route.app) { endpoint_id: endpoint_id, - feature_category: feature_category + feature_category: feature_category, + request_urgency: request_urgency.name } end end @@ -42,7 +53,8 @@ module Gitlab Gitlab::RequestEndpoints.all_controller_actions.map do |controller, action| { endpoint_id: controller.endpoint_id_for_action(action), - feature_category: controller.feature_category_for_action(action) + feature_category: controller.feature_category_for_action(action), + request_urgency: controller.urgency_for_action(action).name } end end diff --git a/lib/gitlab/metrics/requests_rack_middleware.rb b/lib/gitlab/metrics/requests_rack_middleware.rb index 3a0e34d5615..c143a7f5a1b 100644 --- a/lib/gitlab/metrics/requests_rack_middleware.rb +++ b/lib/gitlab/metrics/requests_rack_middleware.rb @@ -79,7 +79,7 @@ module Gitlab if !health_endpoint && ::Gitlab::Metrics.record_duration_for_status?(status) self.class.http_request_duration_seconds.observe({ method: method }, elapsed) - record_apdex_if_needed(env, elapsed) + record_apdex(env, elapsed) end [status, headers, body] @@ -113,12 +113,12 @@ module Gitlab ::Gitlab::ApplicationContext.current_context_attribute(:caller_id) end - def record_apdex_if_needed(env, elapsed) - return unless Gitlab::Metrics::RailsSlis.request_apdex_counters_enabled? + def record_apdex(env, elapsed) + urgency = urgency_for_env(env) Gitlab::Metrics::RailsSlis.request_apdex.increment( - labels: labels_from_context, - success: satisfactory?(env, elapsed) + labels: labels_from_context.merge(request_urgency: urgency.name), + success: elapsed < urgency.duration ) end @@ -129,17 +129,15 @@ module Gitlab } end - def satisfactory?(env, elapsed) - target = + def urgency_for_env(env) + endpoint_urgency = if env['api.endpoint'].present? env['api.endpoint'].options[:for].try(:urgency_for_app, env['api.endpoint']) elsif env['action_controller.instance'].present? && env['action_controller.instance'].respond_to?(:urgency) env['action_controller.instance'].urgency end - target ||= Gitlab::EndpointAttributes::DEFAULT_URGENCY - - elapsed < target.duration + endpoint_urgency || Gitlab::EndpointAttributes::DEFAULT_URGENCY end end end diff --git a/lib/gitlab/metrics/samplers/action_cable_sampler.rb b/lib/gitlab/metrics/samplers/action_cable_sampler.rb index 043d2ae84cc..adce3030d0d 100644 --- a/lib/gitlab/metrics/samplers/action_cable_sampler.rb +++ b/lib/gitlab/metrics/samplers/action_cable_sampler.rb @@ -39,23 +39,14 @@ module Gitlab def sample pool = @action_cable.worker_pool.executor - labels = { - server_mode: server_mode - } - - metrics[:active_connections].set(labels, @action_cable.connections.size) - metrics[:pool_min_size].set(labels, pool.min_length) - metrics[:pool_max_size].set(labels, pool.max_length) - metrics[:pool_current_size].set(labels, pool.length) - metrics[:pool_largest_size].set(labels, pool.largest_length) - metrics[:pool_completed_tasks].set(labels, pool.completed_task_count) - metrics[:pool_pending_tasks].set(labels, pool.queue_length) - end - - private - def server_mode - Gitlab::ActionCable::Config.in_app? ? 'in-app' : 'standalone' + metrics[:active_connections].set({}, @action_cable.connections.size) + metrics[:pool_min_size].set({}, pool.min_length) + metrics[:pool_max_size].set({}, pool.max_length) + metrics[:pool_current_size].set({}, pool.length) + metrics[:pool_largest_size].set({}, pool.largest_length) + metrics[:pool_completed_tasks].set({}, pool.completed_task_count) + metrics[:pool_pending_tasks].set({}, pool.queue_length) end end end diff --git a/lib/gitlab/metrics/subscribers/action_view.rb b/lib/gitlab/metrics/subscribers/action_view.rb index fa129025bfe..bc9032a6942 100644 --- a/lib/gitlab/metrics/subscribers/action_view.rb +++ b/lib/gitlab/metrics/subscribers/action_view.rb @@ -40,7 +40,7 @@ module Gitlab end def current_transaction - ::Gitlab::Metrics::Transaction.current + ::Gitlab::Metrics::WebTransaction.current end end end diff --git a/lib/gitlab/metrics/subscribers/external_http.rb b/lib/gitlab/metrics/subscribers/external_http.rb index 60a1b084345..ff8654a2cec 100644 --- a/lib/gitlab/metrics/subscribers/external_http.rb +++ b/lib/gitlab/metrics/subscribers/external_http.rb @@ -43,7 +43,7 @@ module Gitlab private def current_transaction - ::Gitlab::Metrics::Transaction.current + ::Gitlab::Metrics::WebTransaction.current || ::Gitlab::Metrics::BackgroundTransaction.current end def add_to_detail_store(start, payload) diff --git a/lib/gitlab/metrics/subscribers/rails_cache.rb b/lib/gitlab/metrics/subscribers/rails_cache.rb index 45344e79796..b5e087d107b 100644 --- a/lib/gitlab/metrics/subscribers/rails_cache.rb +++ b/lib/gitlab/metrics/subscribers/rails_cache.rb @@ -65,7 +65,7 @@ module Gitlab private def current_transaction - ::Gitlab::Metrics::Transaction.current + ::Gitlab::Metrics::WebTransaction.current end def metric_cache_operation_duration_seconds diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb index 97cc8bed564..56a310548a7 100644 --- a/lib/gitlab/metrics/transaction.rb +++ b/lib/gitlab/metrics/transaction.rb @@ -6,35 +6,14 @@ module Gitlab class Transaction include Gitlab::Metrics::Methods - # base label keys shared among all transactions - BASE_LABEL_KEYS = %i(controller action feature_category).freeze # labels that potentially contain sensitive information and will be filtered FILTERED_LABEL_KEYS = %i(branch path).freeze - THREAD_KEY = :_gitlab_metrics_transaction - # The series to store events (e.g. Git pushes) in. EVENT_SERIES = 'events' attr_reader :method - class << self - def current - Thread.current[THREAD_KEY] - end - - def prometheus_metric(name, type, &block) - fetch_metric(type, name) do - # set default metric options - docstring "#{name.to_s.humanize} #{type}" - - evaluate(&block) - # always filter sensitive labels and merge with base ones - label_keys BASE_LABEL_KEYS | (label_keys - FILTERED_LABEL_KEYS) - end - end - end - def initialize @methods = {} end @@ -126,10 +105,6 @@ module Gitlab histogram.observe(filter_labels(labels), value) end - def labels - BASE_LABEL_KEYS.product([nil]).to_h - end - def filter_labels(labels) labels.empty? ? self.labels : labels.without(*FILTERED_LABEL_KEYS).merge(self.labels) end diff --git a/lib/gitlab/metrics/web_transaction.rb b/lib/gitlab/metrics/web_transaction.rb index 544c142f7bb..fcfa86734e8 100644 --- a/lib/gitlab/metrics/web_transaction.rb +++ b/lib/gitlab/metrics/web_transaction.rb @@ -2,12 +2,37 @@ module Gitlab module Metrics + # Exclusive transaction-type metrics for web servers (including Web/Api/Git + # fleet). One instance of this class is created for each request going + # through the Rack metric middleware. Any metrics dispatched with this + # instance include metadata such as controller, action, feature category, + # etc. class WebTransaction < Transaction + THREAD_KEY = :_gitlab_metrics_transaction + BASE_LABEL_KEYS = %i(controller action feature_category).freeze + CONTROLLER_KEY = 'action_controller.instance' ENDPOINT_KEY = 'api.endpoint' ALLOWED_SUFFIXES = Set.new(%w[json js atom rss xml zip]) SMALL_BUCKETS = [0.1, 0.25, 0.5, 1.0, 2.5, 5.0].freeze + class << self + def current + Thread.current[THREAD_KEY] + end + + def prometheus_metric(name, type, &block) + fetch_metric(type, name) do + # set default metric options + docstring "#{name.to_s.humanize} #{type}" + + evaluate(&block) + # always filter sensitive labels and merge with base ones + label_keys BASE_LABEL_KEYS | (label_keys - ::Gitlab::Metrics::Transaction::FILTERED_LABEL_KEYS) + end + end + end + def initialize(env) super() @env = env |