Skip to content

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

@theFong

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions