feat: add opt-in proxychains-style terminal chain visual#7
Conversation
- Add format_chain_visual() and print_chain_visual() to supervisor.py - Extract _extract_hop_label() and _all_hops_ok() helpers to avoid duplication - Call visual at startup (topology) and on hop health state changes in hop_health_loop - Add logging.chain_visual: false option to both config files - Add 9 new tests in tests/test_supervisor.py (81 total, all pass) - Document chain_visual option with example output in README.md Co-authored-by: P4X-ng <223870169+P4X-ng@users.noreply.github.com>
|
/gemini review @codex review or bitch about your environment |
There was a problem hiding this comment.
Code Review
This pull request introduces a well-implemented and useful feature: an optional, proxychains-style terminal visualization for the hop chain. The changes are comprehensive, including updates to documentation, configuration, core logic, and thorough testing. The code is clean, robust, and the feature is disabled by default to avoid impacting existing log pipelines. I have one minor suggestion to improve the robustness of the visual output formatting.
There was a problem hiding this comment.
Pull request overview
Adds an opt-in, terminal-friendly “proxychains-style” ASCII visualization of the configured proxy chain and hop health, intended to be printed to stderr to avoid polluting structured stdout logs.
Changes:
- Implemented chain visual formatting + gated
stderrprinting, and integrated it into startup and hop health monitoring. - Added
logging.chain_visual: falseto example configs (disabled by default). - Added unit tests and README documentation for the new visual output.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
egressd/supervisor.py |
Adds chain visual formatting/printing functions and hooks them into main and hop_health_loop. |
egressd/config.json5 |
Documents and defaults logging.chain_visual to false. |
egressd/config.host.example.json5 |
Documents and defaults logging.chain_visual to false. |
tests/test_supervisor.py |
Adds tests for topology-only and health-status chain visuals, plus stderr gating. |
README.md |
Adds a “Chain visual” section explaining usage and showing example output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def _capture_stderr(self, fn, *args, **kwargs) -> str: | ||
| """Call *fn* with redirected stderr and return whatever was written.""" | ||
| buf = io.StringIO() | ||
| old_stderr = sys.stderr | ||
| try: | ||
| sys.stderr = buf | ||
| fn(*args, **kwargs) | ||
| finally: | ||
| sys.stderr = old_stderr | ||
| return buf.getvalue() |
There was a problem hiding this comment.
_capture_stderr reassigns the global sys.stderr, which can interfere with other tests if the suite is ever run in parallel. Consider using the standard library helper (contextlib.redirect_stderr) for the same behavior with clearer intent, and keep the redirected scope as small as possible.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ea7ee57be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
egressd/supervisor.py
Outdated
| if parsed.hostname and parsed.port: | ||
| return f"{parsed.hostname}:{parsed.port}" | ||
| except (ValueError, AttributeError): | ||
| pass | ||
| return raw_url |
There was a problem hiding this comment.
Sanitize hop labels before falling back to raw URL
_extract_hop_label falls back to raw_url when the parsed URL has no explicit port, so a hop like http://user:pass@proxy will be printed with embedded credentials when chain visual output is enabled. Because preflight allows hop URLs without ports, this path is reachable in production configs and leaks secrets to stderr/log capture. Strip userinfo and derive a default port instead of returning the original URL.
Useful? React with 👍 / 👎.
| current_ok = _all_hops_ok(hops, statuses) | ||
| if first_run or current_ok != last_overall_ok: | ||
| print_chain_visual(cfg, statuses) |
There was a problem hiding this comment.
Trigger chain visual on any hop-status change
hop_health_loop only reprints when the aggregate _all_hops_ok(...) boolean flips, so per-hop transitions are suppressed whenever overall state stays unhealthy (for example, one failed hop is replaced by a different failed hop). This leaves operators with stale chain diagnostics despite real hop changes. Track and compare per-hop status (or an ok tuple) rather than a single aggregate flag before deciding to print.
Useful? React with 👍 / 👎.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Adds a terminal-friendly ASCII chain visualization inspired by classic proxychains output. Disabled by default (
logging.chain_visual: false) so it doesn't pollute JSON log pipelines.What it looks like
Written to
stderrso it stays separate from structured stdout logs.Changes
egressd/supervisor.py_extract_hop_label(hop)— parseshost:portfrom a hop config dict_all_hops_ok(hops, statuses)— shared predicate used in both the visual andhop_health_loopformat_chain_visual(cfg, hop_statuses)— pure function returning the ASCII stringprint_chain_visual(cfg, hop_statuses)— gate onlogging.chain_visual, writes tostderrhop_health_loop— callsprint_chain_visualon first run and whenever overall-ok state flipsmain— prints topology visual immediately after config loads (before first probe)egressd/config.json5/egressd/config.host.example.json5—logging.chain_visual: falsewith commenttests/test_supervisor.py— 9 new tests covering topology-only, all-ok, partial failure, single-hop, empty chain, andprint_chain_visualenable/disableREADME.md— new Chain visual section with example outputOriginal prompt
💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.
Note
Low Risk
Low risk: adds an opt-in stderr-only chain visualization gated by
logging.chain_visual, with limited new logic in the hop health loop and coverage via unit tests.Overview
Adds an opt-in proxychains-style ASCII chain visualization (
logging.chain_visual) that prints the configured hop topology at startup and reprints whenever overall hop health flips, writing to stderr to avoid polluting JSON stdout logs.Updates sample configs to include
chain_visual: false, documents the feature and example output in the README, and adds unit tests covering formatting and the enable/disable behavior.Written by Cursor Bugbot for commit 9c7d1ae. Configure here.