From bc87b48007812f9835a54f9fad00a2bf173dac0c Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Tue, 5 Nov 2024 10:00:09 -0500 Subject: [PATCH 1/7] feat: add aggregated metrics for rails and more This adds aggregated metrics for the following plugins: * rails * net_http * sidekiq Similar to the Karafka plugin, there is now more configuration: * `rails.insights.events` * `rails.insights.metrics` * `sidekiq.insights.events` * `sidekiq.insights.metrics` * `net_http.insights.events` * `net_http.insights.metrics` --- lib/honeybadger/config/defaults.rb | 40 ++++++++++++ lib/honeybadger/instrumentation.rb | 2 +- lib/honeybadger/notification_subscriber.rb | 61 +++++++++++++------ lib/honeybadger/plugins/active_job.rb | 1 - lib/honeybadger/plugins/net_http.rb | 20 +++++- lib/honeybadger/plugins/sidekiq.rb | 14 +++-- .../unit/honeybadger/plugins/net_http_spec.rb | 6 +- 7 files changed, 116 insertions(+), 28 deletions(-) diff --git a/lib/honeybadger/config/defaults.rb b/lib/honeybadger/config/defaults.rb index 318e315a..2478af72 100644 --- a/lib/honeybadger/config/defaults.rb +++ b/lib/honeybadger/config/defaults.rb @@ -363,6 +363,36 @@ class Boolean; end default: 60, type: Integer }, + :'sidekiq.insights.enabled' => { + description: 'Enable automatic data collection for Sidekiq.', + default: true, + type: Boolean + }, + :'sidekiq.insights.events' => { + description: 'Enable automatic event capturing for Sidekiq.', + default: true, + type: Boolean + }, + :'sidekiq.insights.metrics' => { + description: 'Enable automatic metric data collection for Sidekiq.', + default: true, + type: Boolean + }, + :'rails.insights.enabled' => { + description: 'Enable automatic data collection for Ruby on Rails.', + default: true, + type: Boolean + }, + :'rails.insights.events' => { + description: 'Enable automatic event capturing for Ruby on Rails.', + default: true, + type: Boolean + }, + :'rails.insights.metrics' => { + description: 'Enable automatic metric data collection for Ruby on Rails.', + default: true, + type: Boolean + }, :'karafka.insights.enabled' => { description: 'Enable automatic data collection for Karafka.', default: true, @@ -383,6 +413,16 @@ class Boolean; end default: true, type: Boolean }, + :'net_http.insights.events' => { + description: 'Enable automatic event capturing for Net::HTTP requests.', + default: true, + type: Boolean + }, + :'net_http.insights.metrics' => { + description: 'Enable automatic metric data collection for Net::HTTP requests.', + default: true, + type: Boolean + }, :'net_http.insights.full_url' => { description: 'Record the full request url during instrumentation.', default: false, diff --git a/lib/honeybadger/instrumentation.rb b/lib/honeybadger/instrumentation.rb index 9de5cb99..62d00946 100644 --- a/lib/honeybadger/instrumentation.rb +++ b/lib/honeybadger/instrumentation.rb @@ -134,7 +134,7 @@ def gauge(name, *args) elsif block_given? value = yield else - value = attributes.delete(:value) + value = attributes.delete(:duration) || attributes.delete(:value) end Honeybadger::Gauge.register(registry, name, attributes).tap do |gauge| diff --git a/lib/honeybadger/notification_subscriber.rb b/lib/honeybadger/notification_subscriber.rb index eeaf4770..177f5784 100644 --- a/lib/honeybadger/notification_subscriber.rb +++ b/lib/honeybadger/notification_subscriber.rb @@ -3,6 +3,29 @@ module Honeybadger class NotificationSubscriber + include Honeybadger::InstrumentationHelper + + Metric = Struct.new(:type, :event, :value_key, :context) + + RAILS_METRICS = [ + Metric.new(:gauge, 'sql.active_record', :duration, %i[query]), + + Metric.new(:gauge, 'process_action.action_controller', :duration, %i[method controller action format status]), + Metric.new(:gauge, 'process_action.action_controller', :db_runtime, %i[method controller action format status]), + Metric.new(:gauge, 'process_action.action_controller', :view_runtime, %i[method controller action format status]), + + Metric.new(:gauge, 'cache_read.active_support', :duration, %i[store key]), + Metric.new(:gauge, 'cache_fetch_hit.active_support', :duration, %i[store key]), + Metric.new(:gauge, 'cache_write.active_support', :duration, %i[store key]), + Metric.new(:gauge, 'cache_exist?.active_support', :duration, %i[store key]), + + Metric.new(:gauge, 'render_partial.action_view', :duration, %i[view]), + Metric.new(:gauge, 'render_template.action_view', :duration, %i[view]), + Metric.new(:gauge, 'render_collection.action_view', :duration, %i[view]), + + Metric.new(:gauge, 'perform.active_job', :duration, %i[job_class queue_name]) + ] + def start(name, id, payload) @start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end @@ -21,7 +44,27 @@ def finish(name, id, payload) end def record(name, payload) - Honeybadger.event(name, payload) + if Honeybadger.config.load_plugin_insights_events?(:rails) + Honeybadger.event(name, payload) + end + + if Honeybadger.config.load_plugin_insights_metrics?(:rails) && (metrics = find_metrics(name, payload)) + metric_source 'rails' + metrics.each do |metric| + public_send( + metric.type, + [metric.value_key, metric.event].join('.'), + value: payload[metric.value_key], + **payload.slice(*metric.context) + ) + end + end + end + + def find_metrics(name, payload) + RAILS_METRICS.select do |metric| + metric.event.to_s == name.to_s && payload.keys.include?(metric.value_key) && (payload.keys & metric.context).any? + end end def process?(event, payload) @@ -109,22 +152,6 @@ def format_payload(payload) end end - class ActiveJobMetricsSubscriber < NotificationSubscriber - include Honeybadger::InstrumentationHelper - - def format_payload(payload) - { - job_class: payload[:job].class.to_s, - queue_name: payload[:job].queue_name - } - end - - def record(name, payload) - metric_source 'active_job' - histogram name, { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(payload) - end - end - class ActionMailerSubscriber < NotificationSubscriber end diff --git a/lib/honeybadger/plugins/active_job.rb b/lib/honeybadger/plugins/active_job.rb index 542000e4..12eec561 100644 --- a/lib/honeybadger/plugins/active_job.rb +++ b/lib/honeybadger/plugins/active_job.rb @@ -55,7 +55,6 @@ def context(job) # rubocop:disable Metrics/MethodLength if config.load_plugin_insights?(:active_job) ::ActiveSupport::Notifications.subscribe(/(enqueue_at|enqueue|enqueue_retry|enqueue_all|perform|retry_stopped|discard)\.active_job/, Honeybadger::ActiveJobSubscriber.new) - ::ActiveSupport::Notifications.subscribe('perform.active_job', Honeybadger::ActiveJobMetricsSubscriber.new) end end end diff --git a/lib/honeybadger/plugins/net_http.rb b/lib/honeybadger/plugins/net_http.rb index 80836404..5adc00f5 100644 --- a/lib/honeybadger/plugins/net_http.rb +++ b/lib/honeybadger/plugins/net_http.rb @@ -7,6 +7,12 @@ module Honeybadger module Plugins module Net module HTTP + @@hb_config = ::Honeybadger.config + + def self.set_hb_config(config) + @@hb_config = config + end + def request(request_data, body = nil, &block) return super unless started? return super if hb? @@ -18,19 +24,26 @@ def request(request_data, body = nil, &block) status: response_data.code.to_i }.merge(parsed_uri_data(request_data)) - Honeybadger.event('request.net_http', context) + if @@hb_config.load_plugin_insights_events?(:net_http) + Honeybadger.event('request.net_http', context) + end + + if @@hb_config.load_plugin_insights_metrics?(:net_http) + context.delete(:url) + Honeybadger.gauge('duration.request', context.merge(metric_source: 'net_http')) + end end[1] # return the response data only end def hb? - address.to_s[/#{Honeybadger.config[:'connection.host'].to_s}/] + address.to_s[/#{@@hb_config[:'connection.host'].to_s}/] end def parsed_uri_data(request_data) uri = request_data.uri || build_uri(request_data) {}.tap do |uri_data| uri_data[:host] = uri.host - uri_data[:url] = uri.to_s if Honeybadger.config[:'net_http.insights.full_url'] + uri_data[:url] = uri.to_s if @@hb_config[:'net_http.insights.full_url'] end end @@ -43,6 +56,7 @@ def build_uri(request_data) requirement { config.load_plugin_insights?(:net_http) } execution do + Honeybadger::Plugins::Net::HTTP.set_hb_config(config) ::Net::HTTP.send(:prepend, Honeybadger::Plugins::Net::HTTP) end end diff --git a/lib/honeybadger/plugins/sidekiq.rb b/lib/honeybadger/plugins/sidekiq.rb index 7e940c5a..94d4f433 100644 --- a/lib/honeybadger/plugins/sidekiq.rb +++ b/lib/honeybadger/plugins/sidekiq.rb @@ -38,10 +38,14 @@ def call(worker, msg, queue, &block) raise ensure context.merge!(duration: duration, status: status) - Honeybadger.event('perform.sidekiq', context) + if Honeybadger.config.load_plugin_insights_events?(:sidekiq) + Honeybadger.event('perform.sidekiq', context) + end - metric_source 'sidekiq' - histogram 'perform', { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(context.slice(:worker, :queue, :duration)) + if Honeybadger.config.load_plugin_insights_metrics?(:sidekiq) + metric_source 'sidekiq' + histogram 'perform', { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(context.slice(:worker, :queue, :duration)) + end end end end @@ -55,7 +59,9 @@ def call(worker, msg, queue, _redis) queue: queue } - Honeybadger.event('enqueue.sidekiq', context) + if Honeybadger.config.load_plugin_insights_events?(:sidekiq) + Honeybadger.event('enqueue.sidekiq', context) + end yield end diff --git a/spec/unit/honeybadger/plugins/net_http_spec.rb b/spec/unit/honeybadger/plugins/net_http_spec.rb index a68002cb..e37810d4 100644 --- a/spec/unit/honeybadger/plugins/net_http_spec.rb +++ b/spec/unit/honeybadger/plugins/net_http_spec.rb @@ -6,10 +6,10 @@ before do Honeybadger::Plugin.instances[:net_http].reset! + Honeybadger::Plugin.instances[:net_http].load!(config) end it "includes integration module into Net::HTTP" do - Honeybadger::Plugin.instances[:net_http].load!(config) expect(Net::HTTP.ancestors).to include(Honeybadger::Plugins::Net::HTTP) end @@ -19,15 +19,17 @@ context "report domain only" do it "contains a domain" do expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, host: "example.com"})) + expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) Net::HTTP.get(URI.parse('http://example.com')) end end context "report domain and full url" do - before { ::Honeybadger.config[:'net_http.insights.full_url'] = true } + before { config[:'net_http.insights.full_url'] = true } it "contains a domain and url" do expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, url: "http://example.com", host: "example.com"})) + expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) Net::HTTP.get(URI.parse('http://example.com')) end end From 611f3b53ea1dc5deafeb01a8d42f952e03c39904 Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Wed, 6 Nov 2024 10:16:01 -0500 Subject: [PATCH 2/7] Switch sidekiq histogram to gauge instead --- lib/honeybadger/plugins/sidekiq.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/honeybadger/plugins/sidekiq.rb b/lib/honeybadger/plugins/sidekiq.rb index 94d4f433..4760dad9 100644 --- a/lib/honeybadger/plugins/sidekiq.rb +++ b/lib/honeybadger/plugins/sidekiq.rb @@ -44,7 +44,7 @@ def call(worker, msg, queue, &block) if Honeybadger.config.load_plugin_insights_metrics?(:sidekiq) metric_source 'sidekiq' - histogram 'perform', { bins: [30, 60, 120, 300, 1800, 3600, 21_600] }.merge(context.slice(:worker, :queue, :duration)) + gauge 'perform', context.slice(:worker, :queue, :duration) end end end From fbddd81bffbd19af9d60cd523c47f0363031d45b Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Wed, 6 Nov 2024 11:07:02 -0500 Subject: [PATCH 3/7] Also send totals so we can get proper averages --- lib/honeybadger/gauge.rb | 1 + lib/honeybadger/histogram.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/honeybadger/gauge.rb b/lib/honeybadger/gauge.rb index 7113e49f..80288706 100644 --- a/lib/honeybadger/gauge.rb +++ b/lib/honeybadger/gauge.rb @@ -19,6 +19,7 @@ def record(value) def payloads [ { + total: @total, min: @min, max: @max, avg: @avg, diff --git a/lib/honeybadger/histogram.rb b/lib/honeybadger/histogram.rb index e6f8db59..be637daf 100644 --- a/lib/honeybadger/histogram.rb +++ b/lib/honeybadger/histogram.rb @@ -34,6 +34,7 @@ def bins def payloads [{ + total: @total, min: @min, max: @max, avg: @avg, From cab788a395d2582e5e435cc283fd4d768cbde822 Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Wed, 6 Nov 2024 11:18:19 -0500 Subject: [PATCH 4/7] Update specs --- spec/unit/honeybadger/gauge_spec.rb | 2 +- spec/unit/honeybadger/histogram_spec.rb | 1 + spec/unit/honeybadger/timer_spec.rb | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/unit/honeybadger/gauge_spec.rb b/spec/unit/honeybadger/gauge_spec.rb index b6767f17..44c18a2d 100644 --- a/spec/unit/honeybadger/gauge_spec.rb +++ b/spec/unit/honeybadger/gauge_spec.rb @@ -10,6 +10,6 @@ before { metric.record(1) } - it { should eq [{ avg: 1.0, latest: 1, max: 1, min: 1 }] } + it { should eq [{ total: 1, avg: 1.0, latest: 1, max: 1, min: 1 }] } end end diff --git a/spec/unit/honeybadger/histogram_spec.rb b/spec/unit/honeybadger/histogram_spec.rb index 6ae2fe12..67257671 100644 --- a/spec/unit/honeybadger/histogram_spec.rb +++ b/spec/unit/honeybadger/histogram_spec.rb @@ -13,6 +13,7 @@ it do should eq [ { + total: 1, avg: 1.0, latest: 1, max: 1, diff --git a/spec/unit/honeybadger/timer_spec.rb b/spec/unit/honeybadger/timer_spec.rb index acd1cd7a..23b5cadf 100644 --- a/spec/unit/honeybadger/timer_spec.rb +++ b/spec/unit/honeybadger/timer_spec.rb @@ -10,6 +10,6 @@ before { metric.record(1) } - it { should eq [{ avg: 1.0, latest: 1, max: 1, min: 1 }] } + it { should eq [{ total: 1, avg: 1.0, latest: 1, max: 1, min: 1 }] } end end From 4d77d578186dd2a2c8e78b53ddabe2deb6dc3397 Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Fri, 8 Nov 2024 10:32:15 -0500 Subject: [PATCH 5/7] Refactor improvements, default metric collection to false to avoid duplication --- lib/honeybadger/config/defaults.rb | 9 +++-- lib/honeybadger/notification_subscriber.rb | 45 ++++++---------------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/lib/honeybadger/config/defaults.rb b/lib/honeybadger/config/defaults.rb index 2478af72..59ee327e 100644 --- a/lib/honeybadger/config/defaults.rb +++ b/lib/honeybadger/config/defaults.rb @@ -32,6 +32,7 @@ class Boolean; end 'Sidekiq::JobRetry::Skip'].map(&:freeze).freeze IGNORE_EVENTS_DEFAULT = [ + { event_type: 'metric.hb', metric_name: 'duration.sql.active_record', query: /^(begin|commit)( transaction)?$/i }, { event_type: 'sql.active_record', query: /^(begin|commit)( transaction)?$/i }, { event_type: 'sql.active_record', query: /(solid_queue|good_job)/i }, { event_type: 'sql.active_record', name: /^GoodJob/ }, @@ -375,7 +376,7 @@ class Boolean; end }, :'sidekiq.insights.metrics' => { description: 'Enable automatic metric data collection for Sidekiq.', - default: true, + default: false, type: Boolean }, :'rails.insights.enabled' => { @@ -390,7 +391,7 @@ class Boolean; end }, :'rails.insights.metrics' => { description: 'Enable automatic metric data collection for Ruby on Rails.', - default: true, + default: false, type: Boolean }, :'karafka.insights.enabled' => { @@ -405,7 +406,7 @@ class Boolean; end }, :'karafka.insights.metrics' => { description: 'Enable automatic metric data collection for Karafka.', - default: true, + default: false, type: Boolean }, :'net_http.insights.enabled' => { @@ -420,7 +421,7 @@ class Boolean; end }, :'net_http.insights.metrics' => { description: 'Enable automatic metric data collection for Net::HTTP requests.', - default: true, + default: false, type: Boolean }, :'net_http.insights.full_url' => { diff --git a/lib/honeybadger/notification_subscriber.rb b/lib/honeybadger/notification_subscriber.rb index 177f5784..1549a2b7 100644 --- a/lib/honeybadger/notification_subscriber.rb +++ b/lib/honeybadger/notification_subscriber.rb @@ -5,27 +5,6 @@ module Honeybadger class NotificationSubscriber include Honeybadger::InstrumentationHelper - Metric = Struct.new(:type, :event, :value_key, :context) - - RAILS_METRICS = [ - Metric.new(:gauge, 'sql.active_record', :duration, %i[query]), - - Metric.new(:gauge, 'process_action.action_controller', :duration, %i[method controller action format status]), - Metric.new(:gauge, 'process_action.action_controller', :db_runtime, %i[method controller action format status]), - Metric.new(:gauge, 'process_action.action_controller', :view_runtime, %i[method controller action format status]), - - Metric.new(:gauge, 'cache_read.active_support', :duration, %i[store key]), - Metric.new(:gauge, 'cache_fetch_hit.active_support', :duration, %i[store key]), - Metric.new(:gauge, 'cache_write.active_support', :duration, %i[store key]), - Metric.new(:gauge, 'cache_exist?.active_support', :duration, %i[store key]), - - Metric.new(:gauge, 'render_partial.action_view', :duration, %i[view]), - Metric.new(:gauge, 'render_template.action_view', :duration, %i[view]), - Metric.new(:gauge, 'render_collection.action_view', :duration, %i[view]), - - Metric.new(:gauge, 'perform.active_job', :duration, %i[job_class queue_name]) - ] - def start(name, id, payload) @start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end @@ -48,22 +27,22 @@ def record(name, payload) Honeybadger.event(name, payload) end - if Honeybadger.config.load_plugin_insights_metrics?(:rails) && (metrics = find_metrics(name, payload)) + if Honeybadger.config.load_plugin_insights_metrics?(:rails) metric_source 'rails' - metrics.each do |metric| - public_send( - metric.type, - [metric.value_key, metric.event].join('.'), - value: payload[metric.value_key], - **payload.slice(*metric.context) - ) - end + record_metrics(name, payload) end end - def find_metrics(name, payload) - RAILS_METRICS.select do |metric| - metric.event.to_s == name.to_s && payload.keys.include?(metric.value_key) && (payload.keys & metric.context).any? + def record_metrics(name, payload) + case name + when 'sql.active_record' + gauge('duration.sql.active_record', value: payload[:duration], **payload.slice(:query)) + when 'process_action.action_controller' + gauge('duration.process_action.action_controller', value: payload[:duration], **payload.slice(:method, :controller, :action, :format, :status)) + gauge('db_runtime.process_action.action_controller', value: payload[:db_runtime], **payload.slice(:method, :controller, :action, :format, :status)) + gauge('view_runtime.process_action.action_controller', value: payload[:view_runtime], **payload.slice(:method, :controller, :action, :format, :status)) + when /^cache_.*.active_support$/ + gauge("duration.#{name}", value: payload[:duration], **payload.slice(:store, :key)) end end From 96baff17608b30ba6d982f40c3b801004e32d9b4 Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Fri, 8 Nov 2024 10:37:39 -0500 Subject: [PATCH 6/7] Add separate context for enabling metrics --- .../unit/honeybadger/plugins/net_http_spec.rb | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/spec/unit/honeybadger/plugins/net_http_spec.rb b/spec/unit/honeybadger/plugins/net_http_spec.rb index e37810d4..8fad12bf 100644 --- a/spec/unit/honeybadger/plugins/net_http_spec.rb +++ b/spec/unit/honeybadger/plugins/net_http_spec.rb @@ -19,7 +19,6 @@ context "report domain only" do it "contains a domain" do expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, host: "example.com"})) - expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) Net::HTTP.get(URI.parse('http://example.com')) end end @@ -29,9 +28,30 @@ it "contains a domain and url" do expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, url: "http://example.com", host: "example.com"})) - expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) Net::HTTP.get(URI.parse('http://example.com')) end end + + context "metrics collection enabled" do + let(:config) { Honeybadger::Config.new(logger: NULL_LOGGER, debug: true, :'insights.enabled' => true, :'net_http.insights.metrics' => true) } + + context "report domain only" do + it "contains a domain" do + expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, host: "example.com"})) + expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) + Net::HTTP.get(URI.parse('http://example.com')) + end + end + + context "report domain and full url" do + before { config[:'net_http.insights.full_url'] = true } + + it "contains a domain and url" do + expect(Honeybadger).to receive(:event).with('request.net_http', hash_including({method: "GET", status: 200, url: "http://example.com", host: "example.com"})) + expect(Honeybadger).to receive(:gauge).with('duration.request', hash_including({method: "GET", status: 200, host: "example.com"})) + Net::HTTP.get(URI.parse('http://example.com')) + end + end + end end end From 8bdf71552d20801d23cae2efea97762ed252a1ee Mon Sep 17 00:00:00 2001 From: Roel Bondoc Date: Fri, 8 Nov 2024 10:48:23 -0500 Subject: [PATCH 7/7] Forgot to add back active_job metric --- lib/honeybadger/notification_subscriber.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/honeybadger/notification_subscriber.rb b/lib/honeybadger/notification_subscriber.rb index 1549a2b7..ea210b83 100644 --- a/lib/honeybadger/notification_subscriber.rb +++ b/lib/honeybadger/notification_subscriber.rb @@ -41,6 +41,8 @@ def record_metrics(name, payload) gauge('duration.process_action.action_controller', value: payload[:duration], **payload.slice(:method, :controller, :action, :format, :status)) gauge('db_runtime.process_action.action_controller', value: payload[:db_runtime], **payload.slice(:method, :controller, :action, :format, :status)) gauge('view_runtime.process_action.action_controller', value: payload[:view_runtime], **payload.slice(:method, :controller, :action, :format, :status)) + when 'perform.active_job' + gauge('duration.perform.active_job', value: payload[:duration], **payload.slice(:job_class, :queue_name)) when /^cache_.*.active_support$/ gauge("duration.#{name}", value: payload[:duration], **payload.slice(:store, :key)) end