Monita

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

  1. In a project, open Heartbeats and select New heartbeat.
  2. Enter a Name, for example nightly-backup.
  3. 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.
  4. 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.
  5. 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.
  6. Pick the Alert level and set When it fails. These fields work as on a monitor, but a heartbeat has no failed-check count.
  7. 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.

PartShows
Ping URLThe URL, with a copy button
Call it from your jobThree blocks to copy, in Shell, Node.js or Python. Monita remembers your choice in this browser.
SettingsRuns 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 /fail URL 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.

ButtonDoes
PauseShows 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.
ResumeShows when any picked heartbeat is paused. It resumes the paused ones, and reads Resume N when the pick is mixed.
Plan maintenanceOpens the maintenance form with the picked heartbeats ticked.
DeleteAsks 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 selectionUnticks 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

RuleValue
Pings per heartbeat1 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 tokens404, never limited: a token is random, so guessing one is hopeless
Request bodyRead up to 16 MiB within 10 s; only /fail keeps its first 1 KB
Pings kept7 days

The token is the secret. Anyone with the URL can ping. Rotate it by deleting the heartbeat and making a new one.

Edit this page on GitHub