Collectors

Keeping the Collector Running

Once a collector is enrolled, you want it to stay up on its own — through a crash, a logout, or a host reboot. Versus does this with two layers: the bundled supervisor that restarts the collector and safely self-upgrades it, and your OS service manager that keeps the supervisor alive across reboots. Ready-to-paste units for each platform are below.

Layer 1 — the supervisor

Ships in every collector archive. Launches the collector, restarts it if it exits, and performs signed, health-checked self-upgrades with automatic rollback. Keeps the collector alive while the host is up.

Layer 2 — your OS

systemd / Task Scheduler / launchd / a container runtime starts the supervisor on boot and brings it back after a reboot. Keeps the supervisor alive across boots.

NoteThe collector is outbound-only and fail-safe — if connectivity drops it pauses at the last checkpoint and resumes when the link returns, so a restart is always safe. Its control channel is outbound (a WSS channel it re-dials, or a per-call HTTPS long-poll as fallback), so a brief network blip self-heals with no intervention.

The supervisor — what it does

The collector archive contains two binaries — collector and supervisor(.exe on Windows) — plus a README. Run the supervisor; it runs the collector for you. It:

  • Restarts the collector if the child process exits for any reason.
  • Self-upgrades safely. When a new signed version is published it stages it, launches it, and gives it a window to establish a healthy control-plane session — if it doesn't, it rolls back to the previous version. A collector never gets stuck on a bad build.
  • Shares one state directory with the collector (enrollment identity, keys, staged versions), set with -state-dir.

Run command

Enroll once (see Installing the Collector Agent), then run the supervisor pointed at the same state directory:

supervisor -state-dir <state-dir> -collector-bin ./collector
  • -state-dir — the collector's state directory (the supervisor forces the collector to use the same one). Use a path the run-as user owns.
  • -collector-bin — path to the collector binary you extracted.
  • -manifest-url <URL> -update-pubkey <HEX> — optional; enable signed self-upgrade (both values come from Client Tools). Omit them and the supervisor still restarts the collector on crash — it just won't auto-update.
  • -collector-args "--enroll-url <URL> --enroll-token <TOKEN>" — first run only, if you enroll through the supervisor rather than the collector directly. The one-time token is consumed once; drop it afterwards.

Everything below wraps that one command in your OS's service manager.

Just need to start an already-enrolled collector again by hand? Run the collector binary with no flags — see Already installed? Starting, restarting and stopping.


Linux — systemd (per-user, no root)

Best for a workstation or shared host where you don't have root. Create~/.config/systemd/user/versus-collector.service:

[Unit]
Description=Versus Collector
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=%h/versus-collector/supervisor -state-dir %h/.local/share/versus-agent -collector-bin %h/versus-collector/collector
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

Enable it, and turn on lingering so it runs without an active login and starts at boot:

loginctl enable-linger "$USER"          # run across logouts + start at boot
systemctl --user daemon-reload
systemctl --user enable --now versus-collector
systemctl --user status versus-collector
journalctl --user -u versus-collector -f   # live logs

Linux — systemd (system-wide, dedicated account)

Best for a server. Runs under an unprivileged versus account and starts at boot before anyone logs in. Create /etc/systemd/system/versus-collector.service:

[Unit]
Description=Versus Collector
After=network-online.target
Wants=network-online.target

[Service]
User=versus
Group=versus
ExecStart=/opt/versus-collector/supervisor -state-dir /var/lib/versus-agent -collector-bin /opt/versus-collector/collector
Restart=always
RestartSec=5
# self-upgrade (optional): append -manifest-url <URL> -update-pubkey <HEX>

[Install]
WantedBy=multi-user.target
sudo useradd -r -s /usr/sbin/nologin versus 2>/dev/null || true
sudo mkdir -p /var/lib/versus-agent && sudo chown versus:versus /var/lib/versus-agent
sudo systemctl daemon-reload
sudo systemctl enable --now versus-collector
sudo systemctl status versus-collector

Windows — Task Scheduler (no admin)

Runs the collector at logon under your account, no elevation. In PowerShell:

schtasks /Create /TN "Versus Collector" /SC ONLOGON /RL LIMITED /F ^
  /TR "\"%USERPROFILE%\versus-collector\supervisor.exe\" -state-dir \"%LOCALAPPDATA%\versus-agent\" -collector-bin \"%USERPROFILE%\versus-collector\collector.exe\""

The supervisor restarts the collector on crash. To also restart the supervisor if it stops, open Task Scheduler → Versus Collector → Properties → Settings and tick “If the task fails, restart every 1 minute.”

Windows — a service (headless, admin)

For a server that must run with no one logged in, wrap the supervisor as a service with NSSM in an elevated prompt:

nssm install VersusCollector "C:\versus-collector\supervisor.exe" ^
  -state-dir "C:\ProgramData\versus-agent" -collector-bin "C:\versus-collector\collector.exe"
nssm set VersusCollector AppExit Default Restart
nssm set VersusCollector Start SERVICE_AUTO_START
nssm start VersusCollector

macOS — launchd

A per-user LaunchAgent needs no admin and starts at login. Create~/Library/LaunchAgents/io.versus.collector.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>io.versus.collector</string>
  <key>ProgramArguments</key><array>
    <string>/Users/YOU/versus-collector/supervisor</string>
    <string>-state-dir</string><string>/Users/YOU/Library/Application Support/versus-agent</string>
    <string>-collector-bin</string><string>/Users/YOU/versus-collector/collector</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/Users/YOU/Library/Logs/versus-collector.log</string>
  <key>StandardErrorPath</key><string>/Users/YOU/Library/Logs/versus-collector.err.log</string>
</dict></plist>
launchctl load ~/Library/LaunchAgents/io.versus.collector.plist
launchctl list | grep versus

KeepAlive relaunches the supervisor if it stops; RunAtLoad starts it at login. For a boot-time (no login) service, place the same plist in /Library/LaunchDaemons/(owned by root) instead.


Docker

If you run the collector in a container, let the runtime supervise it with a restart policy:

docker run -d --name versus-collector --restart unless-stopped \
  -v versus-agent-state:/var/lib/versus-agent \
  <your-collector-image> \
  supervisor -state-dir /var/lib/versus-agent -collector-bin /usr/local/bin/collector

--restart unless-stopped (or restart: unless-stopped in Compose) brings the container back after a crash or a Docker/host restart; mount the state directory as a named volume so enrollment identity survives re-creation.


Verify it stays up

  • Session state. In Collector Fleet → Collectors the collector shows session Active; it reconnects on its own after a network blip.
  • Reboot test. Reboot the host — the collector should return to Activewith no manual step.
  • Crash test. Kill the collector process; the supervisor relaunches it within seconds. Kill the supervisor and your OS service manager restarts it.
  • Logs. systemd: journalctl [--user] -u versus-collector -f; Windows: Task Scheduler history / NSSM logs; macOS: the StandardOutPath file above.

Redundancy

Supervision keeps one collector alive; for site-level resilience, enroll two or more collectors against the same site — Versus distributes work across them and fails over automatically if one goes offline. See Deployment Options and Collector Fleet.