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:
2026-05-27 14:03:01 [INFO] run started task=backup run=01J...2026-05-27 14:03:04 [INFO] run succeeded task=backup run=01J... exit=0 dur=3.5s2026-05-27 14:07:00 [WARN] 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) | Readable 2026-… [INFO] message key=value lines — colored on an interactive terminal, plain everywhere else. |
text | The same readable lines, never colored (plain even on a terminal). |
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
[INFO]summary 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 2026-05-27 14:03:01 (local time) 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 a
full-precision RFC3339 time field.
Readiness and shutdown
Section titled “Readiness and shutdown”Once the daemon’s local API answers, it logs an accurate readiness line:
[INFO] 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:
[INFO] received signal, shutting down signal=interrupt[INFO] draining HTTP requests and closing cloud connection[INFO] stopping scheduler and waiting for in-flight runs in_flight=1 timeout=30s[INFO] shutdown complete elapsed=842ms