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
--limitit pages through everything; with--limitit 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 printwrote <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
| Flag | Meaning |
|---|---|
--step <path> | Only this step path and its descendants. No leading or trailing /. |
--follow | Stream 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
| Code | Meaning |
|---|---|
| 0 | Lines delivered (an interrupted --follow is still 0). |
| 1 | The run lookup or log read failed. |
| 2 | Usage error. |
Named errors
--follow and --download are mutually exclusiveinvalid 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.