Repository navigation
Description
Summary
There's no CLI command to read the lifecycle / setup-script log of a Brev workspace. Today the only way to see why a Launchable's setup failed is to wait for the VM to become reachable, then brev shell <name> and dig through /var/log/brev/oncreate-lifecycle-script-*.log (Brev's own logging) and any service log the script writes (e.g. journalctl -u <unit>). That's painful for three common scenarios:
- The setup script failed mid-execution — the VM is up but
brev openlands on something that doesn't work. The operator has to know tobrev shell, then know tosudo cata Brev-managed path that isn't documented. - The VM never becomes reachable because the script crashed before SSH came up — operators can't
brev shellat all, so the only signal isbuild_status=CREATE_FAILEDwith no log surface. - Agent/CI harnesses — automation that polls for "did the launchable's setup actually succeed?" has to either re-implement the SSH+cat dance or do a deep readiness probe against the service the setup claimed it would start.
This is the third or fourth time recently we've had a launchable setup fail (most recently: glibc 2.39 mismatch on the openshell-gateway binary, where the launchable VM logged the failure but we had to wait for SSH-reachability to read it).
Reproduction
$ brev --help | grep -i log
# (nothing — no `logs` subcommand exists)
$ brev exec my-vm -- sudo cat /var/log/brev/oncreate-lifecycle-script-019e3e9f-cc6c-7041-b186-54a3a6c703da.log
# works, but requires:
# - knowing the exact UUID of the lifecycle-script-instance run
# - knowing the log file lives under /var/log/brev/
# - the VM being SSH-reachable (precluded when the script panics before sshd starts)
# - sudo, since /var/log/brev is root-owned
$ brev exec my-vm -- sudo journalctl -u dex-ui.service -n 200
# same constraints
When the script fails before SSH comes up — which is what happens for any panic in the early apt/install phase — neither of those work. The user is stuck staring at brev ls --json | jq '.workspaces[].statusMessage' which returns one-line summaries with no log content.
What we'd like
A new subcommand:
# Print the latest lifecycle-script log for a workspace, tailing if --follow.
brev logs <workspace-name-or-id>
brev logs <workspace-name-or-id> --follow # -f for live tail
brev logs <workspace-name-or-id> --tail 200 # last N lines
brev logs <workspace-name-or-id> --since 10m # systemd-style window
brev logs <workspace-name-or-id> --json # one log line per JSON objectBehavior:
- Works before SSH is up. Brev's control plane should expose the lifecycle-script-runner's stdout/stderr via the same channel that already populates
build_statusandstatusMessage. The CLI proxies that stream. - Independent of whether the script's own log path is conventional.
brev logsshows the lifecycle runner's log — what the runner itself emitted while invoking the user-supplied script. If the user's script writes to its own paths (/var/log/dex-ui-launchable/setup.log), those stay where they are; a future flag could enumerate them but isn't part of this MVP. - Includes the failure stage, similar to
kubectl logs --previoussemantics. If the last attempt failed and a new one is pending, default behavior is to show the failed one; a--currentflag swaps to the in-progress run. - Honors
--workspace-group— for orgs with multiple workspace groups (GCP/AWS/etc.), pull from whichever the workspace lives in. Mostly transparent. - Output format — plain text by default with one log line per terminal line;
--jsonfor scripts. Don't ANSI-color when piped.
Why this matters
- Debugging the dex-ui launchable above would have been a one-liner:
brev logs dex-ui-launchtest --follow. Instead we waited for SSH, ransudo cat, found a path, and copy-pasted the GLIBC error. - Agent harnesses can short-circuit a smoke test the moment the setup fails instead of waiting for a network-level readiness probe to time out.
build_status=CREATE_FAILEDrecords hold zero diagnostic information today —brev logsis the obvious place that information should appear.
Non-goals
- Application logs from arbitrary services on the VM.
brev exec <name> -- journalctl -u fooalready works once SSH is up; the gap is specifically the lifecycle-script log when SSH isn't yet available. - A general "fetch any file from a workspace's filesystem" API. The launchable lifecycle log is a discrete, well-defined surface; broaden later if needed.
Related
- Workspace stuck in build_status=CREATE_FAILED forever even though the VM is actually RUNNING + HEALTHY + reachable #384 —
build_status=CREATE_FAILEDshould expose enough context to debug without SSH
Activity