Appearance
Runtime logs
Each supervised runtime gets its own log directory:
<host-home>/logs/runtimes/<runtimeId>/
stdout.log
stderr.logMatrixHostService.startRuntimeProcess (matrix-host-service.ts:374-378) opens these as append-mode write streams. The child process's stdout and stderr are piped directly into them; the Host does not interpret their contents.
Format
Whatever the runtime writes. The Host adds nothing — no timestamp, no runtime id prefix, no JSON wrapping. If the runtime writes plain text, that's what ends up on disk. If it writes JSON-Lines, that's what ends up on disk.
The system-gateway-http runtime writes a structured JSON-Lines log; most others write human-readable text.
Lifetime
- Created when the runtime first spawns; reopened (append) on every restart.
- Closed when the runtime exits and the supervisor records its final status (
matrix-host-service.ts:466-470). - Never rotated by the Host. On a
.debinstall, journald rotation applies to the Host's own stdout/stderr but not these per-runtime files. See Logs.
A long-running runtime accumulates log volume indefinitely. For production deployments, run logrotate against <home>/logs/runtimes/*/{stdout,stderr}.log or a per-package equivalent.
Reading them
bash
# Latest activity for one runtime.
tail -F <home>/logs/runtimes/RUNTIME-HOST-LOCAL-ABC-CHAT/stderr.log
# Aggregate stderr across every runtime.
find <home>/logs/runtimes -name 'stderr.log' -print0 \
| xargs -0 tail -F
# Sort by recency, find the most-recently-active runtime.
ls -lt <home>/logs/runtimes/*/stderr.log | headLog-tail-on-failure
When a runtime fails to start, the Host reads up to 4 KiB of stderr + 2 KiB of stdout from these files and appends them to the failure message via appendRuntimeLogTail (matrix-host-service.ts:1322-1354):
Timed out waiting for runtime control actor system.runtimes.RUNTIME-HOST-LOCAL-ABC-CHAT.control for RUNTIME-HOST-LOCAL-ABC-CHAT: Timed out invoking runtime.ready after 1000ms
stderr:
[runtime] connecting to nats://127.0.0.1:4270
[runtime] Error: ECONNREFUSED nats://127.0.0.1:4270
stdout:So the most common failure cause is visible in the supervisor's reply without an extra tail step. The same tail is included in runtime.json metadata.failedReason when the failure path persists the record.
Why "hivecast logs" does not exist
There is no hivecast logs subcommand. The intentional answer is "use your OS log viewer plus these files," not a unified Matrix log server.
Reasons:
- A unified log command would either tail every runtime simultaneously (a firehose) or require operator-supplied filters (a CLI design problem of its own).
- The OS already does this well (journald, Console.app, Event Viewer,
docker logs). - Per-runtime logs live where systemd cannot reach them (file paths inside
<home>), so a unified view would have to interleave systemd- filesystem logs, which is fragile.
The pattern operators use:
bash
# Host + NATS via journald.
sudo journalctl -u hivecast-host.service hivecast-nats.service -f
# Per-runtime via tail.
tail -F <home>/logs/runtimes/<id>/stderr.logSee docs-hivecast/content/cli/exit-codes-and-diagnostics.md for the canonical statement.
Common log signatures
| First line of stderr | Likely cause | Fix |
|---|---|---|
Error: connect ECONNREFUSED 127.0.0.1:4270 | NATS sibling not running | Check hivecast status / journalctl -u hivecast-nats.service |
Error: Cannot find module ... | Package store missing or stale; usually packages/system not seeded | hivecast seed --home <home> |
Timed out invoking runtime.ready | Runtime spawned but never bound runtime.ready on its control mount | Check the runtime's own startup; package bug |
permission denied: /var/lib/hivecast/logs/... | .deb install owned by hivecast user; you ran wrapper as a different user | chown -R or use sudo consistently |