Skip to content

feat: headless mode with a JSONL event stream - #600

Closed
domcyrus wants to merge 1 commit into
refactor/bootstrap-splitfrom
feat/headless
Closed

feat: headless mode with a JSONL event stream#600
domcyrus wants to merge 1 commit into
refactor/bootstrap-splitfrom
feat/headless

Conversation

@domcyrus

@domcyrus domcyrus commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Headless front-end (PR 2 of 3, stacked on #598; retarget to main once that merges).

  • rustnet --headless runs the full pipeline (capture, DPI, attribution, GeoIP, DNS, sandbox, uid drop) without a terminal and streams startup, new_connection, connection_closed, and optional snapshot events as JSON lines to stdout. --log-level goes to stderr.
  • --snapshot-interval SECONDS emits the whole connection table periodically; --filter QUERY restricts the stream using the interactive filter syntax and is validated before any privileged work.
  • Connection events are serde structs in src/headless/events.rs, shared by stdout, --json-log, and the PCAP sidecar (same keys and value types as before; key order is now struct order). Stdout writes go through a bounded queue and a dedicated writer thread, so a slow consumer drops events instead of stalling capture; a closed pipe ends the run cleanly.
  • Exit is 0 on SIGINT/SIGTERM/SIGHUP or a closed stdout, 1 on capture failure.
  • Docs: USAGE (en, zh-CN) with a Headless Mode section, README (en, zh-CN, ja), ARCHITECTURE, INSTALL Docker example, ROADMAP, CHANGELOG. Closes Machine readable logging #9.

Verified: fmt, clippy, cargo test --workspace (default and no-default-features), real headless runs on macOS (Seatbelt) and Linux (OrbStack, Landlock ABI 8, eBPF attribution), including --json-log parity, --filter, the EPIPE path, and the new spawn tests in tests/headless_cli.rs.

Known: new_connection fires on the first packet, so attribution and DPI usually land in connection_closed and snapshot events instead (documented). No Windows console control handler yet, so Ctrl+C there exits without draining the queue (documented, follow-up).

- --headless runs the full pipeline without a terminal and streams startup, new_connection, connection_closed, and snapshot events to stdout
- --snapshot-interval and --filter (interactive filter syntax) for the stream; --log-level goes to stderr
- connection events are serde structs shared by stdout, --json-log, and the PCAP sidecar; stdout writes go through a bounded queue and a writer thread
- docs in en, zh-CN, and ja
@domcyrus

domcyrus commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #602, stacked on #599. The retained implementation now has corrected snapshot semantics, secure output handling, and verified shutdown behavior. All checks pass.

@domcyrus domcyrus closed this Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant