A Laravel Telescope-inspired request monitoring dashboard for Rails applications. Binocs provides real-time visibility into HTTP requests through both a web interface and a terminal UI with vim-style navigation, making debugging and development easier whether you prefer the browser or the command line.
Binocs is short for binoculars — the trusty tool train engineers and conductors used to look down the tracks and inspect what's coming. Now you can do the same for your Rails requests.
- Real-time Request Monitoring: Watch requests stream in as they happen via ActionCable/Turbo Streams
- Comprehensive Request Details: View params, headers, request/response bodies, logs, and exceptions
- Powerful Filtering: Filter by HTTP method, status code, path, controller, and more
- Exception Tracking: Quickly identify and debug errors with full backtrace
- Performance Insights: Track request duration and memory usage
- Dark Theme UI: Beautiful, modern interface built with Tailwind CSS
- Terminal UI (TUI): Vim-style keyboard navigation for console-based monitoring
- AI Agent Integration: Launch Claude Code or OpenCode directly from request context to debug issues
- Swagger Integration: View OpenAPI documentation for requests and jump to Swagger UI
- Production Safe: Automatically disabled in production environments
Real-time request monitoring with filtering and status indicators
Detailed view showing params, headers, body, logs, and exceptions
Vim-style navigation in your terminal
Split-screen detail view with tabbed content
Launch AI coding agents directly from request context
- Ruby 3.0+
- Rails 7.0+
- ActionCable (for real-time updates)
- ncurses development libraries (for TUI - typically pre-installed on macOS/Linux)
# Gemfile
gem 'binocs'bundle installbin/rails generate binocs:installThis will:
- Copy the migration file
- Create an initializer at
config/initializers/binocs.rb - Add the route to mount the engine
bin/rails db:migrateIf you haven't set up ActionCable yet, add to your config/cable.yml:
development:
adapter: async
test:
adapter: test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>bin/rails serverOpen your browser and navigate to: http://localhost:3000/binocs
Customize Binocs behavior in config/initializers/binocs.rb:
Binocs.configure do |config|
# Enable/disable Binocs (automatically disabled in production)
config.enabled = true
# How long to keep request records (default: 24 hours)
config.retention_period = 24.hours
# Maximum request/response body size to store (default: 64KB)
config.max_body_size = 64.kilobytes
# Paths to ignore (assets, cable, etc.)
config.ignored_paths = %w[/assets /packs /binocs /cable]
# Content types to ignore (images, videos, etc.)
config.ignored_content_types = %w[image/ video/ audio/ font/]
# Maximum number of requests to store (oldest are deleted)
config.max_requests = 1000
# Whether to record request/response bodies
config.record_request_body = true
config.record_response_body = true
# Optional: Protect the dashboard with basic auth
config.basic_auth_username = ENV['BINOCS_USERNAME']
config.basic_auth_password = ENV['BINOCS_PASSWORD']
# Swagger/OpenAPI integration (for TUI)
config.swagger_spec_url = '/api-docs/v1/swagger.yaml' # OpenAPI spec endpoint
config.swagger_ui_url = '/api-docs/index.html' # Swagger UI URL
# Devise authentication (recommended if using Devise with ActionCable)
# config.authentication_method = :authenticate_user!
# Login path for authentication prompts (auto-detected for Devise)
# config.login_path = '/users/sign_in'
endIf your application uses Devise for authentication, you can require users to be logged in before accessing Binocs. This ensures the ActionCable WebSocket connection works properly.
# config/initializers/binocs.rb
Binocs.configure do |config|
# Require Devise authentication (recommended)
config.authentication_method = :authenticate_user!
# Or for admin users:
# config.authentication_method = :authenticate_admin!
# Or use a custom proc for more control:
# config.authentication_method = -> { authenticate_user! || authenticate_admin! }
endWith this configured, unauthenticated users will be redirected to your login page, then back to /binocs after signing in.
Fallback behavior: If authentication is not configured but ActionCable requires it, Binocs will detect the WebSocket failure and display a banner prompting users to sign in. You can customize the login path:
config.login_path = '/users/sign_in' # Auto-detected from Devise if not setTo enable jumping directly to specific endpoints in Swagger UI, add deep linking to your rswag configuration:
# config/initializers/rswag_ui.rb
Rswag::Ui.configure do |c|
c.swagger_endpoint '/api-docs/v1/swagger.yaml', 'API V1 Docs'
# Enable deep linking to specific operations
c.config_object['deepLinking'] = true
endWith this enabled, pressing o in the TUI detail view will open Swagger UI and expand the matching endpoint.
The main dashboard shows a list of all recorded requests with:
- HTTP method (GET, POST, PUT, PATCH, DELETE)
- Status code (color-coded by type)
- Request path
- Controller#action
- Duration
- Timestamp
Use the filter bar to narrow down requests:
- Search: Search by path, controller, or action
- Method: Filter by HTTP method
- Status: Filter by status code range (2xx, 3xx, 4xx, 5xx)
- Controller: Filter by controller name
- Has Exception: Show only requests with exceptions
Click on any request to see full details including:
- Overview: Method, path, status, duration, memory usage
- Params: Filtered request parameters
- Headers: Request and response headers
- Body: Request and response bodies (with JSON formatting)
- Logs: Captured log entries from the request
- Exception: Full exception details with backtrace (if applicable)
Requests appear in the dashboard in real-time as they're made to your application. The dashboard uses Turbo Streams over ActionCable for instant updates without page refresh.
Binocs uses Rails' ActionCable and Turbo Streams to provide real-time updates to the dashboard. Here's how the pieces fit together:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Your App │ │ Binocs │ │ Dashboard │
│ Request │────▶│ Middleware │────▶│ (Browser) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ ▲
│ 1. Save to DB │
│ 2. Broadcast │
▼ │
┌─────────────────┐ │
│ Turbo Stream │─────────────┘
│ (ActionCable) │ WebSocket
└─────────────────┘
-
Middleware Intercepts Request: The
Binocs::Middleware::RequestRecordersits in your Rails middleware stack and captures every HTTP request (except ignored paths like/assets,/cable, etc.) -
Data Collection: For each request, Binocs records:
- HTTP method, path, full URL
- Request/response headers and bodies
- Parameters (filtered for sensitive data)
- Controller and action names
- Duration and memory usage
- Any exceptions that occurred
- Log entries generated during the request
-
Database Storage: The request data is saved to the
binocs_requeststable -
Real-time Broadcast: After saving, Binocs broadcasts the new request via Turbo Streams:
Turbo::StreamsChannel.broadcast_prepend_to( "binocs_requests", target: "requests-list", partial: "binocs/requests/request", locals: { request: request } )
-
Dashboard Updates: The dashboard subscribes to the
binocs_requestsstream via ActionCable. When a broadcast arrives, Turbo automatically prepends the new request to the list.
The dashboard establishes a WebSocket connection when you load the page:
<%= turbo_stream_from "binocs_requests" %>This creates a subscription to the binocs_requests channel. The connection uses your application's existing ActionCable configuration (config/cable.yml).
If your application uses Devise (or similar) with ActionCable authentication, the WebSocket connection requires the user to be authenticated. Binocs handles this in two ways:
-
Recommended: Configure
authentication_methodto require login before accessing Binocs (see Devise Integration) -
Fallback: If WebSocket fails to connect, Binocs displays a banner prompting the user to sign in. The dashboard still works without real-time updates - you can use the Refresh button.
The dashboard includes a "Live/Paused" toggle. When paused:
- The Turbo Stream subscription is temporarily disabled
- No new requests appear automatically
- Click "Refresh" to manually load new requests
WebSocket not connecting:
- Check that ActionCable is configured in
config/cable.yml - Verify the
/cablepath is accessible - Check browser console for WebSocket errors
- If using Devise, ensure you're authenticated
Requests not appearing in real-time:
- Verify
Turbo::StreamsChannelis available (requiresturbo-railsgem) - Check Rails logs for
[Binocs] Broadcasting new requestmessages - Ensure the request path isn't in
config.ignored_paths
High latency or missed updates:
- Consider using Redis adapter for ActionCable in production-like environments
- The async adapter (default for development) works fine for local debugging
Binocs includes a full-featured terminal interface for monitoring requests directly from your console. Run it alongside your Rails server for a vim-style debugging experience.
From your Rails application directory:
bundle exec binocsOr if you're in the binocs gem directory:
cd /path/to/your/rails/app
bundle exec binocsList View:
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
g / Home |
Go to top |
G / End |
Go to bottom |
Ctrl+d / PgDn |
Page down |
Ctrl+u / PgUp |
Page up |
Enter / l |
View request details |
/ |
Search by path |
f |
Open filter menu |
c |
Clear all filters |
r |
Refresh list |
d |
Delete selected request |
D |
Delete all requests |
? |
Show help |
q |
Quit |
Detail View:
| Key | Action |
|---|---|
Tab / ] / L |
Next tab |
Shift+Tab / [ / H |
Previous tab |
1-8 |
Jump to tab by number |
j / ↓ |
Scroll down |
k / ↑ |
Scroll up |
n |
Next request |
p |
Previous request |
o |
Open Swagger docs in browser |
h / Esc |
Go back to list |
- Split-screen layout: List on left, detail on right when viewing a request
- Tabbed detail view: Overview, Params, Headers, Body, Response, Logs, Exception, Swagger, Agent
- AI Agent integration: Launch coding agents with request context directly from the TUI
- Swagger integration: View OpenAPI docs for any request and open in browser with
o - Color-coded: HTTP methods and status codes are highlighted by type
- Auto-refresh: List automatically updates every 2 seconds
- Filtering: Same filtering capabilities as the web interface
- Responsive: Adapts to terminal size changes
- Easter egg: Press
Spacethensin detail view to discover your request's spirit animal!
Binocs can launch AI coding agents (Claude Code or OpenCode) directly from the context of a captured request. This is useful when you want an AI to help debug or fix an issue based on the request data.
- View a request's details and navigate to the Agent tab (press
aor9) - Configure your agent settings (see below)
- Type your prompt describing what you want the AI to do
- Press
Enteron an empty line to submit - Watch the AI's output in real-time
The agent receives full context about the request including the HTTP method, path, params, headers, request/response bodies, and any exceptions - giving it everything needed to understand and debug the issue.
While in the Agent tab, you can configure how the agent runs:
| Key | Setting | Description |
|---|---|---|
t |
Toggle Tool | Switch between Claude Code and OpenCode. Claude Code uses claude CLI with --dangerously-skip-permissions for autonomous operation. OpenCode uses the opencode CLI. |
w |
Toggle Worktree | Switch between working on your current branch or creating an isolated git worktree. |
Current Branch Mode (default): The agent makes changes directly on your current git branch. Quick and simple for small fixes.
Worktree Mode: Creates a new git worktree and branch (e.g., agent/0117-1423-fix-auth) for the agent to work in. This keeps your current branch clean and lets you review changes before merging. Press w to enable, then enter a name for the worktree/branch.
# config/initializers/binocs.rb
Binocs.configure do |config|
config.agent_tool = :claude_code # or :opencode
config.agent_worktree_base = '../binocs-agents' # where worktrees are created
end# Clear all recorded requests
bin/rails binocs:clear
# Prune old requests (based on retention_period)
bin/rails binocs:prune
# Show statistics
bin/rails binocs:statsBinocs is automatically disabled in production environments. Even if mounted, accessing /binocs in production will return a 403 Forbidden response.
For additional security in development/staging, enable basic auth:
# config/initializers/binocs.rb
Binocs.configure do |config|
config.basic_auth_username = 'admin'
config.basic_auth_password = 'secret'
endBinocs uses Rails' parameter filtering, so sensitive params (like password) are automatically masked. Cookies are not stored for security reasons.
When using the AI Agent feature, Binocs creates temporary files in your project directory that should be added to your .gitignore:
# Binocs AI Agent files
.binocs-context.md
.binocs-prompt.mdIf you use the worktree mode for agents, the default location is ../binocs-agents/ (a sibling directory to your project), so it won't affect your repo. However, if you configure a custom worktree path inside your project, add that path to .gitignore as well.
- Ensure Binocs is enabled: Check
Binocs.enabled?returnstrue - Check the path isn't ignored: Verify the path isn't in
config.ignored_paths - Verify migrations ran: Check the
binocs_requeststable exists
- Ensure ActionCable is configured and running
- Check browser console for WebSocket errors
- Verify you have
turbo_stream_from "binocs_requests"in the layout
- Reduce
config.retention_period - Lower
config.max_requests - Set
config.record_response_body = falseif you don't need response bodies
cd binocs
bundle install
bundle exec rspecgem build binocs.gemspecMIT License. See MIT-LICENSE for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -am 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
