Class: RailsPulse::Middleware::RequestCollector
- Inherits:
-
Object
- Object
- RailsPulse::Middleware::RequestCollector
- Defined in:
- lib/rails_pulse/middleware/request_collector.rb
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app) ⇒ RequestCollector
constructor
A new instance of RequestCollector.
Constructor Details
#initialize(app) ⇒ RequestCollector
Returns a new instance of RequestCollector.
4 5 6 |
# File 'lib/rails_pulse/middleware/request_collector.rb', line 4 def initialize(app) @app = app end |
Instance Method Details
#call(env) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rails_pulse/middleware/request_collector.rb', line 8 def call(env) # Skip if Rails Pulse is disabled return @app.call(env) unless RailsPulse.configuration.enabled # Skip logging if we are already recording RailsPulse activity. This is to avoid recursion issues return @app.call(env) if RequestStore.store[:skip_recording_rails_pulse_activity] req = ActionDispatch::Request.new(env) # Skip RailsPulse engine requests mount_path = RailsPulse.configuration.mount_path || "/rails_pulse" if req.path.start_with?(mount_path) RequestStore.store[:skip_recording_rails_pulse_activity] = true result = @app.call(env) RequestStore.store[:skip_recording_rails_pulse_activity] = false return result end # Check if route should be ignored based on configuration if should_ignore_route?(req) RequestStore.store[:skip_recording_rails_pulse_activity] = true result = @app.call(env) RequestStore.store[:skip_recording_rails_pulse_activity] = false return result end # Clear any previous request data and set a placeholder ID RequestStore.store[:rails_pulse_request_id] = SecureRandom.uuid RequestStore.store[:rails_pulse_operations] = [] start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) controller_action = "#{env['action_dispatch.request.parameters']&.[]('controller')&.classify}##{env['action_dispatch.request.parameters']&.[]('action')}" occurred_at = Time.current # Process request status, headers, response = @app.call(env) duration = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000).round(2) # Collect all tracking data # Deep copy operations array to prevent race condition in async mode operations = RequestStore.store[:rails_pulse_operations] || [] tracking_data = { method: req.request_method, path: req.path, duration: duration, status: status, is_error: status.to_i >= 500, request_uuid: req.uuid, controller_action: controller_action, occurred_at: occurred_at, operations: operations.map(&:dup) } # Send to tracker (non-blocking if async mode enabled) RailsPulse::Tracker.track_request(tracking_data) [ status, headers, response ] ensure RequestStore.store[:skip_recording_rails_pulse_activity] = false RequestStore.store[:rails_pulse_request_id] = nil RequestStore.store[:rails_pulse_operations] = nil end |