Logging
When you run runwisp daemon (in Docker, under systemd, or on a VPS), the daemon
is your only window into what’s happening — there’s no TUI in front of it. So it
talks: a line every time a task starts, succeeds, or fails, plus startup,
readiness, and shutdown detail. This page covers how to tune that output.
These are operational knobs, not task configuration — so they live on flags and
environment variables, never in runwisp.toml. (Your tasks are the source of
truth; how the daemon logs about them is not.)
Run-lifecycle lines
Section titled “Run-lifecycle lines”In daemon mode every run transition produces one concise line:
time=2026-05-27T14:03:01.412+02:00 level=INFO msg="run started" task=backup run=01J...time=2026-05-27T14:03:04.918+02:00 level=INFO msg="run succeeded" task=backup run=01J... exit=0 dur=3.5stime=2026-05-27T14:07:00.231+02:00 level=WARN msg="run failed" task=report run=01J... exit=2 reason=failed dur=412msThat’s it — start, success, failure, and a warning if a task hits the disk-space limit. Per-output-line capture still goes to the per-run log files; these lines are the high-level heartbeat, not a replacement for them.
--log-level (or RUNWISP_LOG_LEVEL) takes debug, info (default), warn,
or error:
runwisp daemon --log-level debugRUNWISP_LOG_LEVEL=debug runwisp daemonAn unrecognized value is rejected with a clear error and a non-zero exit — there’s
no silent fallback to info.
Format
Section titled “Format”--log-format (or RUNWISP_LOG_FORMAT) picks the shape:
| Value | Output |
|---|---|
auto (default) | Colored text on an interactive terminal; plain text everywhere else. |
text | Text handler (color still gated by TTY / NO_COLOR). |
json | One JSON object per line — for Docker/k8s log pipelines, Loki, etc. |
RUNWISP_LOG_FORMAT=json runwisp daemon{ "time": "2026-05-27T14:03:04.918+02:00", "level": "INFO", "msg": "run succeeded", "task": "backup", "run": "01J...", "exit": 0, "dur": 3500000000}Clean logs when piped
Section titled “Clean logs when piped”RunWisp detects whether stderr is a real terminal. When it isn’t — piped into
docker logs, journald, or a file — it automatically:
- drops ANSI color (so you don’t get escape-code garbage in your log files), and
- replaces the multi-section startup banner with a handful of plain
msg=...lines carrying the same facts (version, paths, task count, warnings).
The standard NO_COLOR environment variable also
disables color on a terminal, and --log-format=json is always colorless.
Timestamps
Section titled “Timestamps”Text output is timestamped with RFC3339 (millisecond precision) in daemon mode —
a long-running process needs to record when things happened. The one exception:
under systemd (detected via JOURNAL_STREAM), RunWisp drops its own
timestamps because journald already prepends them. JSON output always keeps the
time field.
Readiness and shutdown
Section titled “Readiness and shutdown”Once the daemon’s local API answers, it logs an accurate readiness line:
msg="ready, listening" url=http://localhost:9477The URL respects [daemon] external_url
when set, and maps a wildcard --host 0.0.0.0 bind to localhost (the address
you actually connect to).
On Ctrl+C / SIGTERM the daemon names the signal, narrates the drain (HTTP
requests, then scheduler and in-flight runs), and prints the total elapsed time:
msg="received signal, shutting down" signal=interruptmsg="draining HTTP requests and closing cloud connection"msg="stopping scheduler and waiting for in-flight runs" in_flight=1 timeout=30smsg="shutdown complete" elapsed=842ms