Zero-dependency Ruby SDK for PeekAPI. Rack middleware that works with Rails, Sinatra, Hanami, and any Rack-compatible framework. Rails auto-integrates via Railtie.
gem install peekapiOr add to your Gemfile:
gem "peekapi"Set environment variables and the Railtie handles everything:
export PEEKAPI_API_KEY=ak_live_xxx
export PEEKAPI_ENDPOINT=https://...The SDK auto-inserts Rack middleware and registers a shutdown hook. No code changes needed.
# config/application.rb
client = PeekApi::Client.new(api_key: "ak_live_xxx")
config.middleware.use PeekApi::Middleware::Rack, client: clientrequire "sinatra"
require "peekapi"
client = PeekApi::Client.new(api_key: "ak_live_xxx")
use PeekApi::Middleware::Rack, client: client
get "/api/hello" do
json message: "hello"
end# config/app.rb
require "peekapi"
client = PeekApi::Client.new(api_key: "ak_live_xxx")
middleware.use PeekApi::Middleware::Rack, client: clientrequire "peekapi"
client = PeekApi::Client.new(api_key: "ak_live_xxx")
client.track(
method: "GET",
path: "/api/users",
status_code: 200,
response_time_ms: 42,
)
# Graceful shutdown (flushes remaining events)
client.shutdown| Option | Default | Description |
|---|---|---|
api_key |
required | Your PeekAPI key |
endpoint |
PeekAPI cloud | Ingestion endpoint URL |
flush_interval |
10 |
Seconds between automatic flushes |
batch_size |
100 |
Events per HTTP POST (triggers flush) |
max_buffer_size |
10_000 |
Max events held in memory |
max_storage_bytes |
5_242_880 |
Max disk fallback file size (5MB) |
max_event_bytes |
65_536 |
Per-event size limit (64KB) |
storage_path |
auto | Custom path for JSONL persistence file |
debug |
false |
Enable debug logging to stderr |
on_error |
nil |
Callback Proc invoked with Exception on flush errors |
- Rack middleware intercepts every request/response
- Captures method, path, status code, response time, request/response sizes, consumer ID
- Events are buffered in memory and flushed in batches on a background thread
- On network failure: exponential backoff with jitter, up to 5 retries
- After max retries: events are persisted to a JSONL file on disk
- On next startup: persisted events are recovered and re-sent
- On SIGTERM/SIGINT: remaining buffer is flushed or persisted to disk
By default, consumers are identified by:
X-API-Keyheader — stored as-isAuthorizationheader — hashed with SHA-256 (stored ashash_<hex>)
Override with the identify_consumer option to use any header:
client = PeekApi::Client.new(
api_key: "...",
identify_consumer: ->(headers) { headers["x-tenant-id"] }
)The callback receives a Hash of lowercase header names and should return a consumer ID string or nil.
- Zero runtime dependencies — uses only Ruby stdlib (
net/http,json,digest) - Background flush — dedicated thread with configurable interval and batch size
- Disk persistence — undelivered events saved to JSONL, recovered on restart
- Exponential backoff — with jitter, max 5 consecutive failures before disk fallback
- SSRF protection — private IP blocking, HTTPS enforcement (HTTP only for localhost)
- Input sanitization — path (2048), method (16), consumer_id (256) truncation
- Per-event size limit — strips metadata first, drops if still too large (default 64KB)
- Graceful shutdown — SIGTERM/SIGINT handlers +
at_exitfallback - Rails Railtie — auto-configures from env vars when Rails is detected
- Ruby >= 3.1
Bug reports and feature requests: peekapi-dev/community
- Fork & clone the repo
- Install dependencies —
bundle install - Run tests —
bundle exec rake test - Submit a PR
MIT