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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# 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 ID to avoid conflicts RequestStore.store[:rails_pulse_request_id] = nil start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) # Temporarily skip recording while we create the route and request RequestStore.store[:skip_recording_rails_pulse_activity] = true route = find_or_create_route(req) controller_action = "#{env['action_dispatch.request.parameters']&.[]('controller')&.classify}##{env['action_dispatch.request.parameters']&.[]('action')}" occurred_at = Time.current request = nil if route request = RailsPulse::Request.create!( route: route, duration: 0, # will update after response status: 0, # will update after response is_error: false, request_uuid: req.uuid, controller_action: controller_action, occurred_at: occurred_at ) RequestStore.store[:rails_pulse_request_id] = request.id end # Re-enable recording for the actual request processing RequestStore.store[:skip_recording_rails_pulse_activity] = false status, headers, response = @app.call(env) duration = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000).round(2) # Temporarily skip recording while we update the request and save operations RequestStore.store[:skip_recording_rails_pulse_activity] = true if request request.update(duration: duration, status: status, is_error: status.to_i >= 500) # Save collected operations operations_data = RequestStore.store[:rails_pulse_operations] || [] operations_data.each do |operation_data| begin RailsPulse::Operation.create!(operation_data) rescue => e Rails.logger.error "[RailsPulse] Failed to save operation: #{e.}" end end end [ 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 |