Class: Httrace::CaptureMiddleware
- Inherits:
-
Object
- Object
- Httrace::CaptureMiddleware
- Defined in:
- lib/httrace.rb
Overview
── CaptureMiddleware ──────────────────────────────────────────────────────
Rack middleware — works with Rails, Sinatra, Grape, and any Rack-compatible app.
Rails (config/application.rb):
config.middleware.use Httrace::CaptureMiddleware, api_key: 'ht_...'
Sinatra:
use Httrace::CaptureMiddleware, api_key: 'ht_...'
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, api_key:, service: 'default', sample_rate: 0.1, exclude_paths: nil, endpoint: nil) ⇒ CaptureMiddleware
constructor
A new instance of CaptureMiddleware.
Constructor Details
#initialize(app, api_key:, service: 'default', sample_rate: 0.1, exclude_paths: nil, endpoint: nil) ⇒ CaptureMiddleware
Returns a new instance of CaptureMiddleware.
40 41 42 43 44 45 46 47 |
# File 'lib/httrace.rb', line 40 def initialize(app, api_key:, service: 'default', sample_rate: 0.1, exclude_paths: nil, endpoint: nil) @app = app @service = service @sample_rate = sample_rate.to_f @exclude = Set.new(exclude_paths || %w[/health /metrics /favicon.ico]) @client = Client.new(api_key, endpoint || DEFAULT_ENDPOINT) end |
Instance Method Details
#call(env) ⇒ Object
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 |
# File 'lib/httrace.rb', line 49 def call(env) path = env['PATH_INFO'] || '/' if @exclude.include?(path) || rand >= @sample_rate return @app.call(env) end # Buffer request body so we can read it AND so the app can read it too raw_input = env['rack.input'] || StringIO.new req_body = raw_input.read env['rack.input'] = StringIO.new(req_body) t_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) status, headers, body_iter = @app.call(env) latency_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t_start) * 1000.0 # Collect response body without consuming it (Rack contract: body is enumerable) resp_parts = [] body_iter.each { |chunk| resp_parts << chunk } resp_body_str = resp_parts.join Thread.new do record(env, req_body, status, headers, resp_body_str, latency_ms) rescue # Never crash end [status, headers, [resp_body_str]] end |