logs: the service's own output
A failure has a log, an exit code and a reason. logs reads the service's own output and the run it belongs to, instead of reassembling a shell one-liner.
One read or a stream
Ask by service name; the port form still works. --once reads once and exits; without it, logs prints the latest lines and keeps following. --lines N bounds a read, and follow mode writes NDJSON, one value per line.
oberth logs api --once
- A service with a listener reads that process's log; a portless worker reads its run's service log file.
- The log file is appended across runs.
--run currentreads only the part of the current run, starting at its recorded offset. --json --oncereturns one document:source,lines,truncated,service,run_id,pidandstatus.
The failure you actually need
--run current --first-error reads the current run and locates the first matching line from a fixed vocabulary: error, exception, fatal, panic, traceback, case-insensitive. It returns the line number and the original text. It is a position, not a root-cause judgment; when nothing matches, the JSON says no_first_error.
oberth logs api --once --json --run current --first-error
The document adds log_offset, an optional run_start_unknown, and first_error with line and text, or no_first_error. If the log rotated past the recorded offset, the read falls back to the start of the file and sets run_start_unknown, so you know the lines may include earlier runs.
A portless worker still has a log
A worker with no listener is not a service without output. oberth logs worker --once reads that run's service log file; the run record supplies the status and the offset.
worker: API health=200
worker: API health=200
worker: API health=200