Class: Woods::SessionTracer::Middleware
- Inherits:
-
Object
- Object
- Woods::SessionTracer::Middleware
- Defined in:
- lib/woods/session_tracer/middleware.rb
Overview
Rack middleware that captures request metadata for session tracing.
Wraps ‘@app.call(env)`, records after response. Extracts controller/action from `env`. Session ID from `X-Trace-Session` header first, falls back to `request.session.id`.
Fire-and-forget writes — ‘rescue StandardError` on recording, never breaks the request.
Constant Summary collapse
- FULL_STORE_INTERFACE =
Full Store interface every backend (FileStore, RedisStore, SolidCacheStore) implements. Middleware itself only calls #record — the read-side methods are used by the session_trace MCP tool and other consumers. Surfaced as a constant so operators can assert the full interface eagerly when they want:
missing = Woods::SessionTracer::Middleware::FULL_STORE_INTERFACE .reject { |m| store.respond_to?(m) } raise "incomplete store: #{missing}" unless missing.empty? %i[record read sessions clear clear_all].freeze
- REQUIRED_STORE_METHODS =
Methods the middleware actually calls at request time. Validated at init so a half-configured store fails loudly at boot.
%i[record].freeze
Instance Method Summary collapse
-
#call(env) ⇒ Array
Rack response triple [status, headers, body].
-
#initialize(app, store:, session_id_proc: nil, exclude_paths: []) ⇒ Middleware
constructor
A new instance of Middleware.
Constructor Details
#initialize(app, store:, session_id_proc: nil, exclude_paths: []) ⇒ Middleware
Returns a new instance of Middleware.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/woods/session_tracer/middleware.rb', line 47 def initialize(app, store:, session_id_proc: nil, exclude_paths: []) raise ArgumentError, 'session tracer middleware requires a store' if store.nil? missing = REQUIRED_STORE_METHODS.reject { |m| store.respond_to?(m) } unless missing.empty? raise ArgumentError, 'session tracer store is missing required methods ' \ "#{missing.inspect} (got #{store.class}). " \ "Required: #{REQUIRED_STORE_METHODS.inspect}. " \ "Full interface: #{FULL_STORE_INTERFACE.inspect}." end @app = app @store = store @session_id_proc = session_id_proc @exclude_paths = exclude_paths end |
Instance Method Details
#call(env) ⇒ Array
Returns Rack response triple [status, headers, body].
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/woods/session_tracer/middleware.rb', line 67 def call(env) start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) status, headers, body = @app.call(env) duration_ms = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - start_time begin record_request(env, status, duration_ms) rescue StandardError # Fire-and-forget — recording failures never break the request end [status, headers, body] end |