Logging
Corral captures logs from every running project and from infrastructure services (DNS and proxy) through a unified disk-backed pipeline. All log entries are persisted to ~/.corral/logs/ with automatic rotation and retention management. You can view, search, and stream logs from the CLI or the macOS app, with filtering by severity, source, stream, and lifecycle phase.
Viewing Logs
All projects:
corral logs
A specific unit — a project, a service, an infrastructure unit, anything
corral status lists:
corral logs my-worker
corral logs postgres
corral logs caddy
A whole stack. A stack has no process of its own, so its logs are the logs
of everything it starts: its members, what those members depend on, and the same
again through any nested stack. That is the same set corral stack start brings
up, which means the Postgres a worker depends on is in view — usually the thing
you were looking for.
corral logs storefront --tail 40
Corral prints which units it widened to on stderr, once, before the logs. Every line is labelled with the unit it came from either way.
Last N entries:
corral logs --tail 20
Log entries show a timestamp, project name, and message:
[2026-04-29 14:32:01] my-app | Ready on http://localhost:8787
[2026-04-29 14:32:05] auth-service | Ready on http://localhost:8788
Stderr entries are displayed in red in the terminal.
Real-Time Streaming
Follow logs as they arrive:
corral logs --follow
Or for a specific project:
corral logs my-worker --follow
In follow mode, Corral shows the most recent 50 entries and then streams new output in real time. Customize the initial history with --tail:
corral logs --follow --tail 10
Searching
Filter logs by text content (case-insensitive):
corral logs --search "error"
Combine with a project filter:
corral logs my-worker --search "database"
Log Persistence and Retention
Logs are persisted to disk in ~/.corral/logs/ via a disk-backed unified pipeline, with separate log files per unit (projects, services, infrastructure). Logs survive daemon restarts — when Corral starts, it reloads the persisted history.
Log files are automatically rotated when they exceed a configurable size (default 10 MB per unit). During rotation, older entries are evicted and the most recent entries are kept. You can configure the retention limit in Settings → Logging.
Failure snapshots are a special category: when a unit fails on its own account, and the way it failed could have produced logs worth keeping, Corral captures a snapshot of the most recent log entries (up to 2,000 by default, configurable in Settings) and stores it in ~/.corral/logs/<unit-id>/snapshots/<timestamp>--<failure-kind>--<snapshot-id>.jsonl. These snapshots are capped at 50 per unit (FIFO eviction).
Not every failure has one. A port conflict, a missing binary, a denied authorization and anything from the licensing layer are all decided before the unit’s own process runs, so there is nothing of its to capture. Neither does a project that failed because something it depends on failed — see the next paragraph for what it gets instead.
When a failure cascades — a project going down because a service it depends on went down — the downstream unit is given its own copy of the root cause’s snapshot, under ~/.corral/logs/<unit-id>/root_cause/. It is a real copy, so it survives the root being recovered, dismissed or deleted, and it keeps the root’s identity: the same snapshot id, and the root’s failure kind rather than the cascade’s. These are capped separately, at 10 per unit, so a crash-looping project cannot evict the forensic explaining why it cascaded.
List them with corral logs snapshots — add a selector to scope the list to one unit — and read one with corral logs --snapshot <id>, which takes a snapshot id, a unique id prefix, or a <selector>:<iso8601> deep-link. If a prefix matches more than one snapshot, Corral reports the candidates rather than picking. Or open the Failure History tab in the macOS app.
In the macOS App
The macOS app provides a visual log viewer accessible from:
- Per-project: The Logs tab in each project’s detail view
- Global: The Logs panel in the sidebar
On Pro projects, browser console output captured by Browser & Network also folds into this unified view, so console messages sit inline with server output.
The log viewer features:
- Styled text display — timestamps in gray, origin labels in secondary color, messages in monospaced font
- Source filter — show all entries, or filter by origin: Corral, Process, Caddy, DNS
- Stream filter — show all, stdout only, or stderr only
- Severity filter — show all, or filter by minimum severity: Debug, Info, Warn, Error
- Lifecycle pills — inline pills next to log entries that mark lifecycle transitions (Starting, Ready, Stopping, Failed)
- Health signal indicators — inline indicators for health state changes (Degraded, Critical, recovered to Nominal)
- Text filter — narrow down entries by content
- Cmd+F find bar — native macOS find bar for in-text search
- Process stderr highlighted in red (system messages are not colored)
- Auto-scroll toggle — follows new output when enabled, disables when you scroll up
- Font size — Cmd+Plus/Minus/0 to adjust, persisted in settings
- Word wrap toggle — in the toolbar menu, persisted in settings
- Clear button and Copy/Export in the toolbar menu
- Horizontal scrolling when word wrap is off
- Failure History tab — each failure opens the snapshot captured at the moment it happened
Log row context menu
Right-click any log row for:
- Copy Line — the full formatted entry (timestamp, origin, message)
- Copy Message — just the message text
- Open URL — when the line contains a URL, open it in your browser
- Filter to This Source — scope the view to the entry’s origin
- Filter to This Severity — scope to the entry’s severity and above
- Star — bookmark the entry
(The log view is a high-performance list without a row-selection model, so these are mouse-only — there are no keyboard accelerators.)
See Working with Projects for more details.
JSON Output
corral logs --json
Each entry includes: id, timestamp, project_id, project_name, stream (stdout/stderr), origin (Corral/Process/Caddy/Dns), and message.