Skip to content

Logs

hal0 logs everything through journald. The API, the dispatcher, every slot — all flow into the system journal under a stable set of unit names. The dashboard tails the same stream over SSE; the CLI gives you raw journalctl access.

UnitWhat it logs
hal0-api.serviceThe main API + dispatcher process.
hal0-slot@<name>.serviceOne per slot — e.g. hal0-slot@primary.service.
hal0-openwebui.serviceThe bundled OpenWebUI on :3001.

For a slot, the simplest tool is the hal0 CLI — it wraps journalctl with sensible defaults:

Terminal window
hal0 slot logs primary # last 100 lines
hal0 slot logs primary --follow # tail (SSE under the hood)

For the API or raw journal access:

Terminal window
journalctl -u hal0-api.service -f
journalctl -u 'hal0-slot@*.service' -f
journalctl -u hal0-api.service --since '10 minutes ago'

The dashboard’s Logs view tails the journal stream over SSE in real time, with:

  • Filter by unit (API / each slot / OpenWebUI).
  • Filter by level (info, warn, error).
  • Free-text grep against the stream.
  • Pause / resume — useful when you’re trying to read a stack trace.

The SSE stream is the same one the CLI’s --follow flag uses, so the dashboard and a terminal --follow show identical output.

The dispatcher writes a decision log for every routing choice — which slot was considered, which was picked, what state each was in, which models were resolved. This is one of the most useful things for diagnosing “why didn’t my request go where I expected?”

In the dashboard, decision logs appear inline in the Logs view filtered to dispatcher.decide. In the CLI:

Terminal window
journalctl -u hal0-api.service -g 'dispatcher.decide'

Every API error is logged with its structured envelope intact — so when a user reports “I got slot.not_ready”, you can grep journald for the exact request:

Terminal window
journalctl -u hal0-api.service -g 'slot.not_ready'

The error code, message, and details block all come through as one JSON line per error.

  • A queryable log API (/api/logs?since=…&unit=…&grep=…) for programmatic log access.
  • Per-request trace IDs propagated end-to-end (API → dispatcher → slot → response).
  • Optional OpenTelemetry export for sites that already have an observability stack.