Class: EzLogsAgent::Capturers::ActiveJobCapturer
- Inherits:
-
Object
- Object
- EzLogsAgent::Capturers::ActiveJobCapturer
- Defined in:
- lib/ez_logs_agent/capturers/active_job_capturer.rb
Overview
ActiveJob hooks for correlation propagation and job execution capture.
This capturer provides first-class ActiveJob support with two responsibilities:
-
**Enqueue-Time (Correlation Propagation)**:
-
Uses ‘before_enqueue` callback to inject correlation_id into job
-
Preserves causal chain: HTTP → Job → Job
-
-
**Execution-Time (Job Capture)**:
-
Uses ‘around_perform` callback to capture job execution as background_job events
-
Restores correlation_id from job
-
Measures duration and captures success/failure outcome
-
Serialization Support
ActiveJob’s metadata hash is NOT automatically serialized. This capturer overrides ‘serialize` and `deserialize` to persist the correlation_id across job serialization (required for Async adapter and other adapters that serialize jobs).
Sidekiq Adapter Detection
If the job’s queue adapter is Sidekiq, this capturer:
-
STILL propagates correlation at enqueue-time
-
SKIPS execution capture (defers to Sidekiq server middleware)
This prevents double events when Sidekiq is the adapter.
Installation
This capturer is automatically installed by Railtie when ActiveJob is detected and ‘capture_jobs = true`.
For manual installation (if not using Rails):
EzLogsAgent::Capturers::ActiveJobCapturer.install
Class Method Summary collapse
-
.capture_execution(job, block) ⇒ Object
Captures job execution as a background_job event.
-
.install ⇒ void
Installs ActiveJob hooks for correlation propagation and job capture.
-
.propagate_correlation(job) ⇒ void
Propagates correlation_id from current context into job.
Class Method Details
.capture_execution(job, block) ⇒ Object
Captures job execution as a background_job event.
Runs at execution-time (when job executes). Skips capture if job uses Sidekiq adapter (prevents double events).
IMPORTANT: When jobs run inline (Async adapter, perform_now, test adapter), they execute in the same thread as the caller (HTTP request or parent job). We must save and restore the previous correlation to avoid clearing the outer context’s correlation. This applies to:
-
Development with Async adapter
-
Production with perform_now calls
-
Test environments
-
Any synchronous job execution
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/ez_logs_agent/capturers/active_job_capturer.rb', line 103 def capture_execution(job, block) return block.call unless EzLogsAgent.configuration.capture_jobs if sidekiq_adapter?(job) EzLogsAgent::Logger.debug("[ActiveJobCapturer] Skipping capture (Sidekiq adapter)") return block.call end if excluded_job_class?(job) EzLogsAgent::Logger.debug("[ActiveJobCapturer] Skipping capture (excluded job class: #{job.class.name})") return block.call end # Save the previous correlation (from HTTP middleware or parent job) # so we can restore it after the job completes previous_correlation = EzLogsAgent::Correlation.current # Use job's propagated correlation, fall back to current context, or generate new correlation_id = extract_correlation(job) || previous_correlation || EzLogsAgent::Correlation.generate EzLogsAgent::Correlation.current = correlation_id start_time = Time.now result = block.call duration_ms = ((Time.now - start_time) * 1000).to_i capture_success(job, correlation_id, duration_ms, start_time) result rescue StandardError => error capture_failure(job, correlation_id, error, start_time) raise ensure # Restore previous correlation instead of unconditionally clearing. # This is critical for inline jobs that run in the same thread as the caller. if previous_correlation EzLogsAgent::Correlation.current = previous_correlation else EzLogsAgent::Correlation.clear end end |
.install ⇒ void
This method returns an undefined value.
Installs ActiveJob hooks for correlation propagation and job capture.
This method is idempotent and can be called multiple times safely.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ez_logs_agent/capturers/active_job_capturer.rb', line 51 def install return unless defined?(ActiveJob) install_serialization_hooks unless @serialization_installed ActiveJob::Base.before_enqueue do |job| ActiveJobCapturer.propagate_correlation(job) end ActiveJob::Base.around_perform do |job, block| ActiveJobCapturer.capture_execution(job, block) end EzLogsAgent::Logger.debug("[ActiveJobCapturer] Hooks installed") rescue StandardError => e EzLogsAgent::Logger.error("[ActiveJobCapturer] Installation failed: #{e.class} - #{e.}") end |
.propagate_correlation(job) ⇒ void
This method returns an undefined value.
Propagates correlation_id from current context into job.
Runs at enqueue-time (when job is scheduled). Stores correlation in ‘ezlogs_correlation_id` attribute which survives serialization/deserialization.
77 78 79 80 81 82 83 84 |
# File 'lib/ez_logs_agent/capturers/active_job_capturer.rb', line 77 def propagate_correlation(job) correlation_id = EzLogsAgent::Correlation.current return unless correlation_id && !correlation_id.empty? job.ezlogs_correlation_id = correlation_id rescue StandardError => e EzLogsAgent::Logger.error("[ActiveJobCapturer] Correlation propagation failed: #{e.class} - #{e.}") end |