{"id":50106961,"url":"https://github.com/beyondlex/ocular","last_synced_at":"2026-05-25T12:01:02.200Z","repository":{"id":359355218,"uuid":"1245525461","full_name":"beyondlex/ocular","owner":"beyondlex","description":"A TUI tool for real-time visualization of middleware traffic. See exactly what your services send to Redis, MySQL, RabbitMQ, Elasticsearch — regardless of programming language.","archived":false,"fork":false,"pushed_at":"2026-05-21T15:11:43.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-21T22:09:59.606Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beyondlex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-21T09:53:59.000Z","updated_at":"2026-05-21T15:21:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/beyondlex/ocular","commit_stats":null,"previous_names":["beyondlex/ocular"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/beyondlex/ocular","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beyondlex%2Focular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beyondlex%2Focular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beyondlex%2Focular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beyondlex%2Focular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beyondlex","download_url":"https://codeload.github.com/beyondlex/ocular/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beyondlex%2Focular/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33392816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-23T11:04:39.699Z","updated_at":"2026-05-25T12:01:02.190Z","avatar_url":"https://github.com/beyondlex.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ocular\n\n**See what your code actually sends to Redis, MySQL, Postgres, MongoDB, RabbitMQ, Elasticsearch — zero code changes, any language.**\n\nA TUI tool for real-time visualization of middleware traffic. Vim-style keybindings. Protocol-aware parsing. Sub-millisecond latency tracking.\n\n![Rust](https://img.shields.io/badge/rust-stable-orange) ![License](https://img.shields.io/badge/license-MIT-blue)\n\n\n\u003cimg max-width=\"1370\" alt=\"ocular\" src=\"https://github.com/user-attachments/assets/565c8dbc-b295-4cec-a4a4-7beb6c0ddab9\" /\u003e\n\n\n\u003cvideo src=\"https://github.com/user-attachments/assets/d4b2803b-2651-4807-9432-3766dd66e9c2\" controls=\"controls\" muted=\"muted\" style=\"max-width: 1370px\" autoplay=\"autoplay\" loop=\"loop\"\u003e\n\u003c/video\u003e\n\n## Why Ocular?\n\n- **Not a packet sniffer** — Ocular understands protocols. You see `SET user:1 \"hello\"`, not hex dumps.\n- **Not language-specific** — Works with Java, Rust, Go, Python, Node.js, anything that speaks TCP.\n- **Not invasive** — No SDK, no code changes. Point your connection to the proxy port and go.\n- **Vim-native UX** — `j/k`, `gg/G`, `/search`, `v`isual select, `y`ank to clipboard. Feels like home.\n\n**Use cases:** Debug N+1 queries, verify cache hits, trace message routing, profile slow queries, audit what your ORM actually sends.\n\n## Origin Story\n\nI inherited a legacy codebase with no tests and needed to refactor it. The problem: clicking a single button on the frontend could trigger requests to Redis, MySQL, RabbitMQ, and who knows what else — but tracing that through layers of spaghetti code was a nightmare.\n\nI didn't want to spend hours reading tangled code just to understand \"what actually happens when I click this button?\" I wanted to **see** it — which services get hit, what data flows where, how long each call takes.\n\nSo I built Ocular. Point your app's connections through it, click the button, and instantly see every query, every cache write, every message published. No code changes, no breakpoints, no guessing.\n\n## Quick Start\n\n```bash\n# Install\nbrew tap beyondlex/tap \u0026\u0026 brew install ocular\n# or: cargo install ocular-cli\n# or: curl -fsSL https://raw.githubusercontent.com/beyondlex/ocular/main/install.sh | sh\n\n# Try it instantly — no services needed\nocular --demo\n```\n\n### With real services\n\n1. Create `ocular.toml`:\n\n```toml\n[[proxy]]\nname = \"redis\"\nprotocol = \"redis\"\nlisten = \"127.0.0.1:16379\"\nremote = \"127.0.0.1:6379\"\n\n[[proxy]]\nname = \"mysql\"\nprotocol = \"mysql\"\nlisten = \"127.0.0.1:13306\"\nremote = \"127.0.0.1:3306\"\n```\n\n2. Run and connect:\n\n```bash\nocular\n# Point your app to proxy ports:\nredis-cli -h 127.0.0.1 -p 16379\nmysql -h 127.0.0.1 -P 13306 -u root -p\n```\n\n```\nYour App ──→ Ocular Proxy (16379) ──→ Redis (6379)\n                    │\n              TUI Dashboard\n```\n\n\u003e **Note:** For MySQL, use `-h 127.0.0.1` (not `localhost`) to ensure TCP connection through the proxy.\n\n## How It Works\n\nOcular runs lightweight TCP proxies between your application and middleware. Traffic flows through transparently while Ocular parses the wire protocol and displays structured events in a terminal dashboard.\n\n## Features\n\n- **Real-time event stream** — watch requests/responses as they happen\n- **Protocol parsing** — human-readable commands instead of raw bytes\n- **Latency tracking** — request→response timing for every operation\n- **Fuzzy filtering** — search by component name or keyword (`/` to activate)\n- **Component selection** — focus on a single middleware in the left panel\n- **Detail inspector** — select any event to see full payload (scrollable)\n- **MySQL ResultSet display** — parsed columns and rows instead of binary\n- **Auto SSL stripping** — MySQL connections work without `--ssl-mode=DISABLED`\n- **Local timezone** — timestamps match your system clock\n- **Vim-style navigation** — `j/k`, `gg`, `G`, `Ngg` line jumps\n- **Visual selection** — `v` to select multiple events, copy or open in editor\n- **Yank to clipboard** — `y` copies command/SQL to system clipboard\n- **Open in $EDITOR** — `e` opens selected commands in vim/nvim\n- **Leader menu** — `Space` opens a command palette\n- **Hot-reload config** — change theme, format, filters without restarting\n- **Hot-reload proxies** — add/remove/modify `[[proxy]]` entries without restarting\n- **Dashboard** — landing page to select and manage proxy groups before connecting\n- **Proxy Groups** — organize proxies by environment (dev, test, prod), switch instantly\n- **Proxy CRUD** — create, edit, delete, inspect proxies from the component pane (`n/e/d/i`)\n- **Component filter** — fuzzy search proxies in the component pane (`/`)\n- **Demo mode** — `--demo` generates simulated traffic for instant preview\n\n## Supported Protocols\n\n| Protocol | Status |\n|----------|--------|\n| Redis (RESP) | ✅ |\n| MySQL | ✅ |\n| PostgreSQL | ✅ |\n| RabbitMQ (AMQP) | ✅ |\n| MongoDB | ✅ |\n| Memcached | ✅ |\n| Kafka | ✅ |\n| HTTP / Elasticsearch | ✅ |\n\n## Keybindings\n\n| Key | Action |\n|-----|--------|\n| `j` / `k` | Navigate events / scroll detail |\n| `gg` | Jump to first event |\n| `G` | Jump to last event |\n| `Ngg` | Jump to event N (e.g. `42gg`) |\n| `Tab` / `Shift+Tab` | Cycle focus: Components → Events → Detail |\n| `/` | Fuzzy filter (match component or command) |\n| `Enter` | Confirm filter / select component |\n| `Esc` | Clear filter or component selection |\n| `v` | Toggle visual (multi-line) selection |\n| `y` | Copy selected command(s) to clipboard |\n| `e` | Open selected command(s) in `$EDITOR` |\n| `Space` | Open leader menu |\n| `?` | Help popup |\n| `q` | Back to dashboard |\n\n### Leader Menu (`Space` + key)\n\n| Key | Action |\n|-----|--------|\n| `h/j/k/l` | Switch panel focus |\n| `c` | Clear all events |\n| `f` | Toggle follow (tail -f) |\n| `p` | Pause/resume event stream |\n| `g` | Switch proxy group |\n| `,` | Open config in `$EDITOR` |\n\n### Component Pane\n\n| Key | Action |\n|-----|--------|\n| `n` | Create new proxy |\n| `e` | Edit selected proxy |\n| `d` | Delete selected proxy |\n| `i` | Inspect proxy details |\n| `/` | Filter proxies (fuzzy search) |\n\n### Dashboard\n\n| Key | Action |\n|-----|--------|\n| `j` / `k` | Navigate groups |\n| `Enter` | Load group and connect |\n| `n` | Create new group |\n| `r` | Rename group |\n| `e` | Edit group file in `$EDITOR` |\n| `d` | Delete group |\n| `/` | Filter groups |\n| `q` | Quit |\n\n## Configuration\n\nOcular looks for `ocular.toml` in the following order:\n\n1. `./ocular.toml` (current directory)\n2. `$XDG_CONFIG_HOME/ocular/ocular.toml`\n3. `~/.config/ocular/ocular.toml`\n\nMultiple instances of the same protocol are supported — just use different names and ports:\n\n```toml\n[[proxy]]\nname = \"redis-cache\"\nprotocol = \"redis\"\nlisten = \"127.0.0.1:16379\"\nremote = \"127.0.0.1:6379\"\n\n[[proxy]]\nname = \"redis-session\"\nprotocol = \"redis\"\nlisten = \"127.0.0.1:16380\"\nremote = \"127.0.0.1:6380\"\n```\n\n## Event Filtering (Exclude / Include)\n## Proxy Groups\n\nOrganize proxies by environment. Groups are stored as separate files in the config directory:\n\n```\n~/.config/ocular/\n├── ocular.toml          # Main config (theme, event_format, exclude rules)\n└── group/\n    ├── dev.toml         # Development proxies\n    ├── test.toml        # Test environment\n    └── prod.toml        # Production (read-only monitoring)\n```\n\nEach group file uses the same `[[proxy]]` format. Proxies defined in `ocular.toml` are treated as the \"default\" group.\n\nOn startup, Ocular shows a **Dashboard** where you select which group to load. You can also switch groups at any time with `Space` → `g`.\n\nCreating a new group from the dashboard (`n`) walks you through naming the group and adding proxies interactively.\n\n\nHide noisy events from the Events panel using `exclude` rules. Use `include` to override excludes and force specific events to remain visible.\n\n```toml\n# Global exclude by protocol\n[exclude.redis]\npatterns = [\"PING\", \"INFO\"]\n\n[exclude.mysql]\npatterns = [\"SELECT 1\"]\n\n# Per-proxy exclude (merged with global)\n[[proxy]]\nname = \"mysql-dev\"\nprotocol = \"mysql\"\nlisten = \"127.0.0.1:13306\"\nremote = \"127.0.0.1:3306\"\n[proxy.exclude]\npatterns = [\"^SET NAMES\"]\nregex = true\n\n# Include overrides exclude\n[proxy.include]\npatterns = [\"PING\"]\n```\n\nEvaluation order: **include match → show** \u003e **exclude match → hide** \u003e **default → show**\n\n| Field | Default | Description |\n|-------|---------|-------------|\n| `patterns` | (required) | List of strings to match against the event command |\n| `case_sensitive` | `false` | Whether matching is case-sensitive |\n| `regex` | `false` | Treat patterns as regular expressions |\n\n## Event Line Format\n\nCustomize how each event line is displayed using a template string:\n\n```toml\nevent_format = \"%{5}index %time [%{-12}component] %command (%latency)\"\n```\n\n| Field | Content |\n|-------|---------|\n| `index` | Line number |\n| `time` | Timestamp (local timezone) |\n| `component` | Component name |\n| `command` | Event command/SQL |\n| `latency` | Request→response duration |\n| `src` | Source address (ip:port) |\n| `dest` | Destination address (ip:port) |\n\nUse `%{N}field` for fixed width (positive = right-aligned, negative = left-aligned). Supports hot-reload.\n\n## Event Log\n\nRecord all proxy events to `events.log` for offline analysis:\n\n```toml\n[event_log]\nenabled = true\ninclude_response = true\ncomponents = [\"redis-cache\", \"mysql\"]\n```\n\nOutput:\n```\n21:08:43.123 [redis-cache] SET user:1 \"hello\" (0.45ms) -\u003e OK\n21:08:43.456 [mysql] SELECT * FROM users (1.23ms) -\u003e ResultSet (19 rows, 3 cols)\n```\n\n## Build from Source\n\n```bash\ncargo build --release\n./target/release/ocular\n```\n\n## Architecture\n\n```\ncrates/\n├── ocular/            # Binary entry point, config loading\n├── ocular-protocol/   # Wire protocol parsers (RESP, MySQL, PG, AMQP, MongoDB, HTTP)\n├── ocular-proxy/      # Async TCP proxy with event broadcasting\n└── ocular-tui/        # Terminal UI (ratatui)\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeyondlex%2Focular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeyondlex%2Focular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeyondlex%2Focular/lists"}