Operations
Alerts and the watchdog
Problems show in the UI first. Alerts push the important ones to your phone, and the watchdog pauses pipelines when something leaves a sane range. This page says what triggers each, where the numbers come from, and where to look when a run is stuck.
Alerts
With an ntfy topic set, the scheduler pushes alerts to the ntfy phone app, each with a link into the UI:
export ORCA_NOTIFY_URL=https://ntfy.sh/$(openssl rand -hex 16) # subscribe to this topic in the app
export ORCA_UI_URL=https://orca.example.com # where the notifications link to
orca notify test # the phone shows "orca: test alert"
Anyone who knows the topic can read what is sent to it, so treat its name as a secret.
On the Hetzner server, NTFY_TOPIC_FILE in hetzner.env sets
this up.
What is sent
| Kind | When | Priority |
|---|---|---|
watchdog | a watchdog rule tripped and paused pipelines | high; a low "resolved" once acknowledged or unpaused |
run-failed | a run failed after its last retry | default |
fill-stalled | a fill has had no fill run finish in ORCA_NOTIFY_FILL_STALL_HOURS (2) | high; "moving again" once it is |
disk | the control host's fullest disk is over ORCA_NOTIFY_DISK_PERCENT (85) | high; "fine again" once it is under |
worker-lost | a remote worker holding runs has been quiet for ORCA_NOTIFY_WORKER_SECONDS (300) | default |
memory-pressure | a host has held new runs for memory pressure for the grace (600 s) with none of morca's runs going | high; "has eased" once it doesn't hold |
your own | a script ran orca notify --kind <kind> | as given |
The same alert, by kind and subject, is sent at most once per
ORCA_NOTIFY_MIN_SECONDS (1800). What was sent is kept in Postgres, so a
restart doesn't send it again. A send that fails is logged without the URL and tried
again later, with a wait that doubles from 30 seconds to 15 minutes. It never blocks
or fails the scheduler.
Settings
The scheduler reads ORCA_NOTIFY_URL (a topic URL, or a server when the
topic comes from a secret), ORCA_NOTIFY_SECRET (a secret holding the
topic), ORCA_NOTIFY_TOKEN or ORCA_NOTIFY_TOKEN_SECRET (an
access token for a protected topic) and ORCA_UI_URL (for the links). The
thresholds above each have a variable of their own. None of these is logged or put in
a message. orca.toml and settings lists them, and
alerts.md has the full detail.
From a script
orca notify --kind backup-failed --subject nightly --priority high "pg_dump failed: $err" orca notify sends an alert held back like the scheduler's. The Hetzner
server's nightly backup uses it when the backup fails.
Ops › Alerts
Ops › Alerts (/ops/alerts, /api/alerts, orca
alerts) lists every alert sent, newest first: its kind, title and message,
links to the run, pipeline, worker or watchdog rule, whether ntfy took it, and whether
an alert that ends is still open. Alerts are kept 90 days. Ops › Control says whether
alerts are on and lists the last few.
The watchdog
The watchdog runs inside the scheduler every ORCA_WATCHDOG_SECONDS (60;
0 turns it off) and reads Postgres only. When a rule passes one of its thresholds it
pauses the pipelines in its scope, records a trip, shows a red banner on
/, Ops › Control and Ops › Pools, and sends a high-priority alert. It
never resumes anything: a person decides when a pipeline runs again. Runs already
going go on.
Rules
| Rule | Trips when (defaults) | Pauses |
|---|---|---|
launches | instances launched in the last hour over 200 | all pipelines |
cost | estimated cost over $3 an hour for 15 minutes, or over $25 in 24 hours | all pipelines |
idle | at least 4 workers averaging under 15% CPU for 10 minutes | the pipelines owning them |
failing | a pipeline's failed attempts in the last hour over 20, or over 50% once 10 have ended | each such pipeline |
stuck | a running run on sampled instances with no progress and no busy host for 30 minutes | that run's pipeline |
control | the control host's memory over 90%, or its fullest disk over 85% | all pipelines |
Each threshold has an ORCA_WATCHDOG_* variable of its own. On the local
runner, as on the Hetzner server, nothing is launched, so there is nothing to price:
cost reads "fixed price" and never trips. The other rules still apply.
The cost elsewhere is an estimate from an on-demand price table.
After a trip
orca watchdog status # each rule, each threshold and value, and the trips
orca watchdog snooze launches 2h # silence a rule while you fix what trips it
orca watchdog ack --all # keep the pipelines paused, hide the banner
orca unpause gharchive # run again; this clears the trip
Fix the cause first: a rule still past its limit trips again on the next pass.
Unpausing a trip's pipelines clears it and sends a "resolved". Every pause, ack and
snooze is audited. /watchdog shows the same as
orca watchdog status, with a snooze form, and every command works from a
laptop with orca --remote <url>
(watchdog.md).
Metrics
Machine metrics
Beside each run's process, the runner starts <binary> sample,
which writes a line of the machine's CPU, memory, disk, disk I/O and network every
ORCA_SAMPLE_SECONDS (5) to the run's metrics/ folder under
ORCA_LOGS. A remote worker does the same beside each run it starts. A
run's page draws them as its Machines card, on the same time axis as its steps. They
are the whole machine's numbers, shared with whatever else ran there; the run's own
peak memory and CPU are in its Resources card
(Machine metrics).
Ops › Control and Ops › Pools
- Ops › Control (
/ops/control,/api/system) is the machine running the scheduler, the UI and Postgres: CPU, memory, disk, network and each container's memory over 24 hours, 7 or 14 days, its memory pressure and whether new runs wait for it, and the local and control-placed runs going, each with its cgroup's memory against its limit. - Ops › Pools (
/ops/pools,/api/pools) is every other machine runs are placed on: EC2 instances, Kubernetes pods and remote workers, with each one's state and last heartbeat. With EC2 in view it also has hosts, cost and runs per hour, and Hosts over time: the hosts that ran during each hour, by role (EC2 heads and workers, the control host, and, since 0.23.0, self-hosted workers that ran a run or were seen that hour).
/metrics
/metrics has Prometheus gauges for the watchdog
(orca_watchdog_tripped, _value and _threshold,
by rule) and for memory pressure (orca_memory_pressure_some_avg10 and the
others, and orca_admission_memory_pressure_held, by host).
Where to look when a run is stuck
- The run's page. A queued run's Status card says why it waits
(
heldandwaitingin its JSON): no room in the grants, memory pressure,max_runs, or waiting for a worker of its pool. The pipeline's page has the same under Waiting, andorca status <pipeline>prints it. - Paused? A watchdog trip or a deploy pauses pipelines, and a paused
pipeline starts nothing. Look for the red banner, or run
orca watchdog status. - Its machine. For a running run, the Machines card shows whether the
machine is busy, out of memory or out of disk. For a pool, Ops › Pools shows whether
its worker is live and when it was last heard from; a worker gone for half
ORCA_STALE_SECONDShas its runs queued again. - The host's pressure. Ops › Control's Memory pressure card, or
memory_pressurein/api/workersfor a worker. - The logs. The run's driver log and its steps' logs, linked from its page.
For a run that failed rather than stalled, see Debugging failures.