Skip to main content
Version: v5.7.0

opschain logs

Included from Basic tier

opschain logs <run-id> [flags]

Reads a run's persisted logs, follows live ones, or downloads them to a file. Also registered as opschain runs logs (opschain docs cli/runs-logs). Three mutually exclusive modes:

  • Read (the default): print the run's log lines. Without --limit it pages through everything; with --limit it prints a single page and, when more lines exist, tells you on stderr: more lines available — resume with --cursor "<cursor>".
  • Follow (--follow): stream new log lines until the run finishes or you interrupt (Ctrl-C exits 0). Against a server each change step is tailed over SSE, re-attaching with the last cursor on transport drops and discovering newly-created steps while the run is live; a workflow run polls the v2 aggregate log read with the server's resume cursor instead.
  • Download (--download <file>): write all lines to a file, then print wrote <n> log lines to <file>.

Lines print as [<step-path>] <line>; with --step the prefix is dropped (the filter already names the step). -o json streams NDJSON documents in follow mode and a page document otherwise; -o yaml separates streamed documents with ---.

Locally the lines come from the per-user store, and an in-flight run's output is readable (and followable) as it happens — a running step's lines land in the store per chunk, never waiting for the step to finish. A local workflow-run id aggregates recursively: every run its workflow steps spawned (nested workflows included) plays back interleaved, each line labelled with the nested step's path under its workflow step (e.g. release/deploy_web/deploy/rollout), and --step scopes to any point in that composed tree. Against a server, change logs are read over the SSE tail endpoint, and workflow-run logs over the v2 aggregate read (LogService.ReadLogLines with an empty step id) — the server-side aggregation of the run's own lines plus every workflow step's nested change's lines, each attributed with its workflow step path, so --step filtering and the [<step-path>] prefixes work identically across the two run families. Resume cursors are opaque, page-scoped tokens: a cursor from an older CLI's v1-format page does not resume on the v2 read. On the server lane a nested workflow run keeps its own logs — read them with its own run id.

Flags​

FlagMeaning
--step <path>Only this step path and its descendants. No leading or trailing /.
--followStream new log lines until interrupted. Mutually exclusive with --download.
--download <file>Write the log lines to this file instead of stdout.
--cursor <cursor>Resume strictly after this keyset cursor (from a previous page's stderr hint or -o json output).
--limit <n>Read a single page of at most this many lines (0 = page through everything).

Exit codes​

CodeMeaning
0Lines delivered (an interrupted --follow is still 0).
1The run lookup or log read failed.
2Usage error.

Named errors​

  • --follow and --download are mutually exclusive
  • invalid step path "<path>": no leading or trailing /
  • run <id> has no step at path "<path>" — exits 1.

The first two exit 2.

Examples​

Everything a run logged:

opschain logs 01999a7e-3c2d-7e50-a9a1-2b7c7f6f4242

Follow one step subtree live on a server:

opschain logs 01999a7e-… --step deploy/migrate --follow --server https://opschain.example.com

Page through a large log:

opschain logs 01999a7e-… --limit 1000
opschain logs 01999a7e-… --limit 1000 --cursor "<cursor from the previous page>"

See also​

  • opschain docs cli/runs-logs — the same command inside the run family.
  • opschain docs cli/runs-create — where runs (and their logs) come from.
  • opschain learn 3.1 — changes on a server, including reading their logs.