Rust-based process supervisor with a local IPC control plane and a rvisor ctl CLI.
It is aimed at the same operational space as supervisord, but uses TOML config and a local Unix socket control API instead of XML-RPC and INI.
- Run a foreground or daemonized supervisor from the same binary.
- Start, stop, restart, reread, update, and reload managed programs through
rvisor ctl. - Stream process events and tail program logs over local IPC.
autostart,autorestart,startsecs,startretries,stopwaitsecs,numprocs, environment injection, and log rotation.priority— control start/stop ordering across programs (lower starts first).user/group— drop privileges per-program before exec.direct_exec— bypasssh -cfor programs that don't need a shell wrapper.- Install and manage a user service through
systemd --useron Linux orlaunchdon macOS. - Daemon restart recovery: state is snapshotted on shutdown and replayed on the next start.
Build from source:
cargo buildInstall from the local checkout:
cargo install --path .Or install directly from Git:
cargo install --git https://github.com/0x9bb1/rvisor.gitRun the test suite:
cargo testGenerate or copy a config template:
rvisor init -o supervisord.toml
# or
cp examples/supervisord.toml ./supervisord.tomlStart the supervisor in the foreground:
rvisor -c ./supervisord.toml runControl it from another shell:
rvisor -c ./supervisord.toml ctl status
rvisor -c ./supervisord.toml ctl start example
rvisor -c ./supervisord.toml ctl tail example --followRun it as a daemon instead:
rvisor -c ./supervisord.toml --daemon runA minimal edit-and-apply workflow looks like this:
$EDITOR ./supervisord.toml
rvisor -c ./supervisord.toml ctl reread
rvisor -c ./supervisord.toml ctl update
rvisor -c ./supervisord.toml ctl statusMinimal example:
[supervisord]
sock_path = "/tmp/rvisor.sock"
[[programs]]
name = "example"
command = "sleep 60"
autostart = true
autorestart = "unexpected"
stdout_log = "/tmp/example.out.log"
stderr_log = "/tmp/example.err.log"See examples/supervisord.toml for a fuller example.
| Field | Type | Default | Description |
|---|---|---|---|
sock_path |
path | /tmp/rvisor.sock |
Unix socket path |
logfile |
path | — | Daemon log file |
pidfile |
path | — | PID file path |
umask |
integer | — | File creation mask (octal) |
minfds |
integer | — | Minimum open file descriptors |
allowed_uids |
list of integers | [] (all allowed) |
UIDs permitted to connect |
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique program name |
command |
string | required | Shell command (or argv if direct_exec = true) |
cwd |
path | — | Working directory |
autostart |
bool | true |
Start automatically with the daemon |
autorestart |
"always" / "never" / "unexpected" |
"unexpected" |
Restart policy |
numprocs |
integer | 1 |
Number of instances |
environment |
table | {} |
Extra environment variables |
stdout_log |
path | — | Stdout log file |
stderr_log |
path | — | Stderr log file |
stdout_log_max_bytes |
integer | — | Rotate stdout log at this size |
stdout_log_backups |
integer | 0 |
Number of rotated stdout backups to keep |
stderr_log_max_bytes |
integer | — | Rotate stderr log at this size |
stderr_log_backups |
integer | 0 |
Number of rotated stderr backups to keep |
startretries |
integer | 3 |
Max restart attempts before FATAL |
startsecs |
integer | 1 |
Seconds to wait before declaring a process RUNNING |
exitcodes |
list of integers | [0] |
Exit codes considered "expected" |
stopsignal |
string | "TERM" |
Signal sent on stop |
stopwaitsecs |
integer | 10 |
Seconds to wait for graceful stop before SIGKILL |
killasgroup |
bool | false |
Send stop signal to entire process group |
priority |
integer | 999 |
Start/stop ordering — lower starts first, higher stops first |
user |
string | — | Run as this Unix user (daemon must have permission) |
group |
string | — | Run as this Unix group |
direct_exec |
bool | false |
Exec command directly without sh -c (splits on whitespace) |
Show process state:
rvisor ctl status
rvisor ctl status exampleControl processes:
rvisor ctl start example
rvisor ctl stop example
rvisor ctl restart example
rvisor ctl signal TERM exampleApply config changes:
rvisor ctl reread
rvisor ctl update
rvisor ctl reloadInspect logs and events:
rvisor ctl tail example
rvisor ctl tail example --follow
rvisor ctl logtail example --stderr --lines 100
rvisor ctl maintail --follow
rvisor ctl eventsUseful output modes:
rvisor ctl status --json
rvisor ctl shell
rvisor versionIf -c is omitted, rvisor searches for a config in this order:
RVISOR_CONFIGwhen set./supervisord.toml./etc/supervisord.toml/etc/supervisord.toml/etc/rvisor/supervisord.toml/etc/supervisor/supervisord.toml../etc/supervisord.tomlrelative to the executable../supervisord.tomlrelative to the executable
Manage a user service:
rvisor -c ./supervisord.toml service install
rvisor service start
rvisor service status
rvisor service enable
rvisor service restartThe service subcommands use systemd --user on Linux and launchd on macOS. The implemented
subcommands are install, uninstall, start, stop, status, enable, disable,
restart, and reload.
On Linux, rvisor service install writes ~/.config/systemd/user/rvisor.service and points
ExecStart at the current rvisor binary with run and the -c path you passed to install.
A typical setup looks like this:
rvisor -c ~/.config/rvisor/supervisord.toml service install
systemctl --user daemon-reload
systemctl --user start rvisor.service
systemctl --user status rvisor.serviceOn macOS, rvisor service install writes ~/Library/LaunchAgents/com.rvisor.plist and uses
launchctl under the hood for start and stop operations:
rvisor -c ~/.config/rvisor/supervisord.toml service install
launchctl load ~/Library/LaunchAgents/com.rvisor.plist
launchctl list com.rvisor