--- title: 'logs' description: 'Live-tail the logs of a running agent installation over a server-sent stream' position: 17 --- # stackbone logs > `stackbone logs` targets a **running agent installation**. With no `--agent` > it runs against the local-dev installation linked to the current project, so > [`stackbone dev`](/docs/cli/reference/dev) must be running. See > [target resolution](/docs/cli/reference/conventions#target-resolution). > This is a stream: `--json` prints one > [envelope](/docs/cli/reference/conventions#json-output) per log line. Live-tail the targeted installation's logs over a server-sent stream. | Command | Purpose | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `stackbone logs tail` | Stream log lines. Server-side filters: `--run `, `--level `, `--q `, `--trace-id `. Client-side: `--since`, `--until`, `--limit`, `--follow`. | The server applies `--level`, `--q` and `--trace-id`. The CLI applies `--since` and `--until` (a duration like `15m`/`2h` or an ISO timestamp) and `--limit` (default `100`) locally as lines arrive: this stream has no server-side time range or pagination. Without `--follow` the tail stops once `--limit` lines have printed; with `--follow` it streams until you hit Ctrl-C. `--level` sets a **minimum** severity. The server keeps every record whose level is at or above the one you name, so `--level warn` keeps `warn` and `error`, while `--level error` keeps `error` alone. `logs tail` does not paginate. It takes no `--cursor`, and no page cursor comes back, so [the pagination contract](/docs/cli/reference/conventions#pagination) the `list` verbs follow does not apply here. `--limit` caps how many lines one tail prints. Scope the tail to a single run with `--run ` to read just that run's lifecycle: the same id you see in [`stackbone runs list`](/docs/cli/reference/runs#stackbone-runs-list). A failed run also carries its own `error` object (a `message`, plus a `stack` when the runtime captured one) on the run record, so read [`stackbone runs get `](/docs/cli/reference/runs#stackbone-runs-get) for why it failed. Human mode prints four fields per line: the ISO timestamp, the level name, the run id (`-` for a line emitted outside any run), then the message. **JSON payload**: one envelope **per line** (not a paged list). The payload is the log record itself — Pino-shaped, with the run and (inside a workflow step) the step it came from, plus a `source` naming where the box read it: ```jsonc { "schema_version": 1, "level": 30, "time": 1717236000000, "msg": "agent booted", "stream": "stdout", "run_id": null, "source": { "run_id": "-", "path": "" }, } ``` `level` is the Pino number (`10` trace … `60` fatal). `run_id` is `null` for a line emitted outside any run — a boot line, a lifecycle event. A line from inside a workflow step also carries `trace_id` (the run's trace) and `step_id`. **Exit codes**: `0` ok (including a clean Ctrl-C stop) · `3` no project · `1` generic (e.g. invalid `--limit`/`--since`). Full table: [Conventions → exit codes](/docs/cli/reference/conventions#exit-codes).