survos / supervisor-bundle
Supervises a configured set of long-running processes and presents them in a multi-pane TUI.
Package info
github.com/survos/supervisor-bundle
Type:symfony-bundle
pkg:composer/survos/supervisor-bundle
Fund package maintenance!
Requires
- php: ^8.5
- survos/tui-extras-bundle: ^2.10
- symfony/config: ^8.1
- symfony/console: ^8.1
- symfony/dependency-injection: ^8.1
- symfony/http-kernel: ^8.1
- symfony/process: ^8.1
- symfony/tui: ^8.1
- symfony/yaml: ^8.1
README
Supervises a configured set of long-running processes and presents them in a multi-pane TUI
dashboard — start them, watch each one's live output in its own pane, and let them restart on
their own. Think foreman/honcho with a built-in terminal UI, built on symfony/process and
symfony/tui.
It also knows how to run one messenger:consume worker per transport (--workflow), so you can
supervise a whole async pipeline with a single command instead of hand-starting a worker per queue.
Installation
composer require survos/supervisor-bundle
symfony/messenger is optional — only the --workflow queue discovery needs it; the supervisor
works as a generic process runner without it.
Usage
1. Supervise processes from a config file
Create supervisor.yaml in your project root:
processes: api: cmd: ['php', 'bin/console', 'app:serve', '-v'] restart: always worker: cmd: ['php', 'bin/console', 'messenger:consume', 'async', '%verbosity%', '--time-limit=3600', '--memory-limit=512M'] restart: always one-shot: cmd: ['php', 'bin/console', 'app:warmup'] restart: never ring_buffer_lines: 5000 # scrollback kept per process follow_by_default: true # panes auto-scroll to the newest line
Then run the dashboard:
php bin/console survos:supervisor # ./supervisor.yaml (or bundle config) php bin/console survos:supervisor -c deploy.yaml # an explicit config php bin/console survos:supervisor --no-tui # stream prefixed lines instead of the TUI
The TUI enables mouse reporting while it is running. The scroll wheel moves through the selected process's log even while the process sidebar has keyboard focus. Scrolling down to the tail restores follow mode. Mouse reporting is disabled automatically when the dashboard exits.
2. Supervise a messenger pipeline (--workflow)
Instead of a config file, point it at a transport code and it runs one supervised
messenger:consume per matching transport — discovered from the messenger transport registry, so it
needs no knowledge of how the queues were defined:
# Every transport named "dataset" or "dataset.*" → dataset.raw, dataset.normalize, dataset.enrich, …
php bin/console survos:supervisor --workflow=dataset
php bin/console survos:supervisor -w dataset --no-tui
This is the one-command way to run and monitor an async workflow: the supervisor is both the runner (it spawns the consumers) and the monitor (each consumer's output in its own pane).
Verbosity passthrough
The supervisor's own verbosity flows down to the processes it spawns. In a cmd, the placeholder
%verbosity% expands to whatever the supervisor was started with:
| you run | %verbosity% becomes |
|---|---|
survos:supervisor |
(nothing — arg dropped) |
survos:supervisor -v |
-v |
survos:supervisor -vv |
-vv |
survos:supervisor -vvv |
-vvv |
survos:supervisor -q |
-q |
--workflow uses the placeholder for its generated consumers, so -w asset -vv gives you
very-verbose workers without any config. It matters for messenger:consume in particular: it only
reports per-message activity (received / handler / ack) from -vv upward, so at -v a slow queue
and a stuck queue look identical in the dashboard.
At normal verbosity the argument is dropped entirely rather than passed as an empty string — an
empty argv element is a real argument to the child (messenger:consume async '' would read it as a
second, nameless transport). You lose nothing by running workers at normal: monolog's
ConsoleHandler maps normal verbosity to Level::Warning, so $logger->error()/->warning() and
$io->error() still reach the pane, and errors survive even -q.
Commands that don't take console verbosity flags simply omit the placeholder.
Configuration reference
Per process:
| key | default | meaning |
|---|---|---|
cmd |
(required) | argv array, e.g. ['php','bin/console','…'] |
restart |
never |
never · on-failure · always |
cwd |
(project dir) | working directory |
env |
{} |
extra environment variables |
autostart |
true |
start with the supervisor (vs. start it manually later) |
backoff |
— | restart backoff: initial (1.0s), max (30.0s), multiplier (2.0) |
Top level:
| key | default | meaning |
|---|---|---|
ring_buffer_lines |
5000 |
scrollback retained per process |
follow_by_default |
true |
panes follow the tail on launch |
Command options
| option | shortcut | description |
|---|---|---|
--config |
-c |
path to a supervisor YAML (default ./supervisor.yaml, then bundle config) |
--workflow |
-w |
supervise one messenger:consume per transport matching this code |
--no-tui |
disable the TUI; stream prefixed output lines to stdout |
License
MIT