1# frozen_string_literal: true 2 3module Gitlab 4 module Metrics 5 # Exclusive transaction-type metrics for background jobs (Sidekiq). One 6 # instance of this class is created for each job going through the Sidekiq 7 # metric middleware. Any metrics dispatched with this instance include 8 # metadata such as endpoint_id, queue, and feature category. 9 class BackgroundTransaction < Transaction 10 THREAD_KEY = :_gitlab_metrics_background_transaction 11 BASE_LABEL_KEYS = %i(queue endpoint_id feature_category).freeze 12 13 class << self 14 def current 15 Thread.current[THREAD_KEY] 16 end 17 18 def prometheus_metric(name, type, &block) 19 fetch_metric(type, name) do 20 # set default metric options 21 docstring "#{name.to_s.humanize} #{type}" 22 23 evaluate(&block) 24 # always filter sensitive labels and merge with base ones 25 label_keys BASE_LABEL_KEYS | (label_keys - ::Gitlab::Metrics::Transaction::FILTERED_LABEL_KEYS) 26 end 27 end 28 end 29 30 def run 31 Thread.current[THREAD_KEY] = self 32 33 yield 34 ensure 35 Thread.current[THREAD_KEY] = nil 36 end 37 38 def labels 39 @labels ||= { 40 endpoint_id: endpoint_id, 41 feature_category: feature_category, 42 queue: queue 43 } 44 end 45 46 private 47 48 def current_context 49 Labkit::Context.current 50 end 51 52 def feature_category 53 current_context&.get_attribute(:feature_category) 54 end 55 56 def endpoint_id 57 current_context&.get_attribute(:caller_id) 58 end 59 60 def queue 61 worker_class = endpoint_id.to_s.safe_constantize 62 return if worker_class.blank? || !worker_class.respond_to?(:queue) 63 64 worker_class.queue.to_s 65 end 66 end 67 end 68end 69