Class: ScoutApm::BackgroundJobIntegrations::SidekiqMiddleware
- Inherits:
-
Object
- Object
- ScoutApm::BackgroundJobIntegrations::SidekiqMiddleware
- Defined in:
- lib/scout_apm/background_job_integrations/sidekiq.rb
Overview
We insert this middleware into the Sidekiq stack, to capture each job, and time them.
Constant Summary collapse
- UNKNOWN_CLASS_PLACEHOLDER =
'UnknownJob'.freeze
- ACTIVE_JOB_KLASS =
'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'.freeze
- DELAYED_WRAPPER_KLASS =
'Sidekiq::Extensions::DelayedClass'.freeze
Instance Method Summary collapse
- #call(_worker, msg, queue) ⇒ Object
-
#job_class(msg) ⇒ Object
Capturing the class name is a little tricky, since we need to handle several cases: 1.
- #latency(msg, time = Time.now.to_f) ⇒ Object
Instance Method Details
#call(_worker, msg, queue) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/scout_apm/background_job_integrations/sidekiq.rb', line 52 def call(_worker, msg, queue) req = ScoutApm::RequestManager.lookup req.annotate_request(:queue_latency => latency(msg)) begin req.start_layer(ScoutApm::Layer.new('Queue', queue)) started_queue = true req.start_layer(ScoutApm::Layer.new('Job', job_class(msg))) started_job = true yield rescue req.error! raise ensure req.stop_layer if started_job req.stop_layer if started_queue end end |
#job_class(msg) ⇒ Object
Capturing the class name is a little tricky, since we need to handle several cases:
-
ActiveJob, with the class in the key ‘wrapped’
-
ActiveJob, but the ‘wrapped’ key is wrong (due to YAJL serializing weirdly), find it in args.job_class
-
DelayedJob wrapper, deserializing using YAML into the real object, which can be introspected
-
No wrapper, just sidekiq’s class
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/scout_apm/background_job_integrations/sidekiq.rb', line 82 def job_class(msg) job_class = msg.fetch('class', UNKNOWN_CLASS_PLACEHOLDER) if job_class == ACTIVE_JOB_KLASS && msg.key?('wrapped') && msg['wrapped'].is_a?(String) begin job_class = msg['wrapped'].to_s rescue ACTIVE_JOB_KLASS end elsif job_class == ACTIVE_JOB_KLASS && msg.try(:[], 'args').try(:[], 'job_class') begin job_class = msg['args']['job_class'].to_s rescue ACTIVE_JOB_KLASS end elsif job_class == DELAYED_WRAPPER_KLASS begin # Extract the info out of the wrapper yml = msg['args'].first deserialized_args = YAML.load(yml) klass, method, *rest = deserialized_args # If this is an instance of a class, get the class itself # Prevents instances from coming through named like "#<Foo:0x007ffd7a9dd8a0>" klass = klass.class unless klass.is_a? Module job_class = [klass, method].map(&:to_s).join(".") rescue DELAYED_WRAPPER_KLASS end end job_class rescue UNKNOWN_CLASS_PLACEHOLDER end |
#latency(msg, time = Time.now.to_f) ⇒ Object
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/scout_apm/background_job_integrations/sidekiq.rb', line 119 def latency(msg, time = Time.now.to_f) created_at = msg['enqueued_at'] || msg['created_at'] if created_at (time - created_at) else 0 end rescue 0 end |