Skip to content

Add brev logs to fetch lifecycle / setup-script logs without SSHing in #392

Description

@theFong

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:

  1. The setup script failed mid-execution — the VM is up but brev open lands on something that doesn't work. The operator has to know to brev shell, then know to sudo cat a Brev-managed path that isn't documented.
  2. The VM never becomes reachable because the script crashed before SSH came up — operators can't brev shell at all, so the only signal is build_status=CREATE_FAILED with no log surface.
  3. 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 object

Behavior:

  1. 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_status and statusMessage. The CLI proxies that stream.
  2. Independent of whether the script's own log path is conventional. brev logs shows 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.
  3. Includes the failure stage, similar to kubectl logs --previous semantics. If the last attempt failed and a new one is pending, default behavior is to show the failed one; a --current flag swaps to the in-progress run.
  4. Honors --workspace-group — for orgs with multiple workspace groups (GCP/AWS/etc.), pull from whichever the workspace lives in. Mostly transparent.
  5. Output format — plain text by default with one log line per terminal line; --json for 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, ran sudo 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_FAILED records hold zero diagnostic information todaybrev logs is the obvious place that information should appear.

Non-goals

  • Application logs from arbitrary services on the VM. brev exec <name> -- journalctl -u foo already 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions