Heartbeats
A heartbeat watches a job that runs on a schedule. The job calls a URL when it finishes. If no call comes in time, Monita opens an incident.
Create one
- In a project, open Heartbeats and select New heartbeat.
- Enter a Name, for example
nightly-backup. - Under Who sees it, pick Only your team or Also the status page. The cards work as on a monitor. A new heartbeat starts on Only your team.
- Set Runs every to the job's schedule: 1, 5, 10, 15 or 30 minutes, 1, 2, 6 or 12 hours, 1, 7 or 30 days.
- Set Can be late by to how late the job may finish: None, 1, 5, 15 or 30 minutes, 1, 2 or 6 hours, or 1 day.
- Pick the Alert level and set When it fails. These fields work as on a monitor, but a heartbeat has no failed-check count.
- Save, then copy the ping URL.
The deadline is the last ping plus Runs every plus Can be late by. Example: a job runs every 1 day, can be late by 1 hour, and pings at 01:00. The next deadline is 02:00 the next day.
The first deadline counts from the moment you save. A heartbeat that never pings still misses its first deadline.
The lists
The Heartbeats page lists each heartbeat with its state, Next ping due, Every, Alert level and Last ping. A heartbeat with no ping yet reads No data yet.
Ping on success
Call the URL with GET, HEAD or POST when the job succeeds. Monita ignores the body of a success ping. Each ping moves the deadline to now plus Runs every plus Can be late by, and closes an open incident.
curl -fsS -m 10 https://monita.example.com/ping/<token>
Report a failure
Add /fail to report a failure at once. Monita opens an incident without waiting for the deadline. Send the reason as plain text in the body. Monita keeps the first 1 KB as the incident's cause.
if ! output=$(backup.sh 2>&1); then
printf '%s' "$output" | curl -fsS -m 10 --data-binary @- https://monita.example.com/ping/<token>/fail
exit 1
fi
curl -fsS -m 10 https://monita.example.com/ping/<token>
The Details panel
On a heartbeat page, select Details beside Edit. A heartbeat with no ping yet shows a card with the URL and a How to call it button that opens the same panel.
| Part | Shows |
|---|---|
| Ping URL | The URL, with a copy button |
| Call it from your job | Three blocks to copy, in Shell, Node.js or Python. Monita remembers your choice in this browser. |
| Settings | Runs every, Can be late by, what a failure does, the status page rule and the creation time |
The three blocks are:
- When the job succeeds: one call to the URL.
- When it fails, with the reason: one call to the
/failURL with a body. - Run the job and report either: a script that runs the job, pings on success, and sends the error as the reason on failure.
The Node.js and Python scripts look like this:
// Node 18 or later. Runs the job, then tells Monita how it went.
const PING = "https://monita.example.com/ping/<token>";
try {
await runJob();
await fetch(PING, { signal: AbortSignal.timeout(10_000) });
} catch (err) {
const reason = String(err?.stack ?? err).slice(-1000);
await fetch(`${PING}/fail`, { method: "POST", body: reason, signal: AbortSignal.timeout(10_000) });
throw err;
}
import traceback
import urllib.request
PING = "https://monita.example.com/ping/<token>"
try:
run_job()
urllib.request.urlopen(PING, timeout=10)
except Exception:
reason = traceback.format_exc()[-1000:].encode()
urllib.request.urlopen(PING + "/fail", data=reason, timeout=10)
raise
A supervisor does not see the ping URL.
Pause a heartbeat
Select Pause on the heartbeat page and confirm. While it is paused:
- Monita still accepts its pings and stores them, but a ping opens and closes nothing.
- Monita watches no deadline, so a missed ping opens no incident and sends no alert.
- The state reads Paused in grey, and the page says Paused since and the time. A grey Paused stamp sits under the title, and its list row has grey stripes.
- The status page hides it.
Pausing closes the heartbeat's open automatic incident without a resolved alert. Its last update reads "Paused by a tech lead." Select Resume and the deadline starts over: now plus Runs every plus Can be late by.
For planned work that should not alert, plan maintenance from the row menu or the batch bar. While a window covers a heartbeat, the page shows a yellow In maintenance stamp and its list row has yellow stripes. A /fail ping in the window is stored as held: the pings table shows it, but the chart and the availability count it as good, and the chart draws the window as grey stripes.
Pause, resume or delete several
Tick the box at the start of each row you want. The box in the heading ticks every heartbeat the list shows now. A bar with N selected replaces the count above the list. A supervisor sees no boxes.
| Button | Does |
|---|---|
| Pause | Shows when any picked heartbeat runs. Asks first, then pauses the picked heartbeats that run. When some are paused already, it reads Pause N and leaves those as they are. |
| Resume | Shows when any picked heartbeat is paused. It resumes the paused ones, and reads Resume N when the pick is mixed. |
| Plan maintenance | Opens the maintenance form with the picked heartbeats ticked. |
| Delete | Asks first. It lists the heartbeats, what goes and what stays. For more than one, type delete N to confirm. Pause instead is in the same dialog. |
| Clear selection | Unticks every row. |
The action covers up to 100 heartbeats and it all happens or nothing does. The row menu at the end of a row holds Edit, Pause or Resume, Plan maintenance and Delete for that heartbeat alone. A deleted heartbeat's URL answers 404 from then on, and its open incident closes with a resolved alert. A script does the same with a write API key. See API.
Pin a heartbeat
Select the pin at the start of a heartbeat's row to keep it at the top of the list and in the first lanes of the project's Overview chart. Each person pins their own, up to 6 heartbeats and 6 monitors in a project and 6 projects. Select the pin again, or Undo in the message, to unpin.
Resolve by hand
A tech lead can post Resolved on a heartbeat's incident, for example when the job is retired. The heartbeat gets a new deadline: now plus Runs every plus Can be late by. A silent job opens a new incident at that time. See Incidents.
More examples
A crontab line:
0 2 * * * /opt/jobs/backup.sh && curl -fsS -m 10 https://monita.example.com/ping/<token>
A systemd service run by a timer:
[Service]
Type=oneshot
ExecStart=/opt/jobs/backup.sh
ExecStartPost=/usr/bin/curl -fsS -m 10 https://monita.example.com/ping/<token>
A Kubernetes CronJob container:
command: ["/bin/sh", "-c", "run-report && wget -q -T 10 -O /dev/null https://monita.example.com/ping/<token>"]
Rules
| Rule | Value |
|---|---|
| Pings per heartbeat | 1 per second by default. Extra pings get 429 and are not stored. The ping accepted in that second keeps the heartbeat alive. /fail has its own limit, so a fail right after a success is heard. A super admin changes this on Rate limits. |
| Unknown tokens | 404, never limited: a token is random, so guessing one is hopeless |
| Request body | Read up to 16 MiB within 10 s; only /fail keeps its first 1 KB |
| Pings kept | 7 days |
The token is the secret. Anyone with the URL can ping. Rotate it by deleting the heartbeat and making a new one.