Skip to content

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.)

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.5s
time=2026-05-27T14:07:00.231+02:00 level=WARN msg="run failed" task=report run=01J... exit=2 reason=failed dur=412ms

That’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:

Terminal window
runwisp daemon --log-level debug
RUNWISP_LOG_LEVEL=debug runwisp daemon

An unrecognized value is rejected with a clear error and a non-zero exit — there’s no silent fallback to info.

--log-format (or RUNWISP_LOG_FORMAT) picks the shape:

ValueOutput
auto (default)Colored text on an interactive terminal; plain text everywhere else.
textText handler (color still gated by TTY / NO_COLOR).
jsonOne JSON object per line — for Docker/k8s log pipelines, Loki, etc.
Terminal window
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
}

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.

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.

Once the daemon’s local API answers, it logs an accurate readiness line:

msg="ready, listening" url=http://localhost:9477

The 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=interrupt
msg="draining HTTP requests and closing cloud connection"
msg="stopping scheduler and waiting for in-flight runs" in_flight=1 timeout=30s
msg="shutdown complete" elapsed=842ms