Späť na blog

Monitoring cron jobov: heartbeat pattern v praxi

· 6 min čítania

HTTP monitoring nezistí, že padol nočný cron. Heartbeat pattern obráti smer: cron sa hlási monitoringu, a ak nezavolá načas, dostanete upozornenie.

Monitoring cron jobov: heartbeat pattern v praxi

Problém: úlohy na pozadí bez HTTP endpointu

Typický backend má cesty:

  • Webové requesty (HTTP/HTTPS na server) - monitorujete uptime check-om.
  • Cron joby (denný backup, mesačná fakturácia, hodinová synchronizácia) - nemajú HTTP endpoint, externý monitoring ich nedokáže sledovať.
  • Workers (Celery, BullMQ, Sidekiq) spracúvajúce frontu - tiež bez HTTP.

Keď cron padne (preklep v crontabe, plný disk, chýbajúca premenná prostredia (environment variable) alebo chyba importu po aktualizácii závislosti (dependency upgrade)), nikto vás neupozorní. Dozviete sa o tom až v pondelok ráno, keď si všimnete, že sa faktúry cez víkend neodoslali.

Heartbeat pattern: cron pinguje monitoring

Princíp je obrátený oproti normálnemu monitoringu:

  1. V monitoring službe vytvoríte heartbeat monitor s očakávaným intervalom (napr. "každých 60 minút").
  2. Dostanete unikátnu heartbeat URL: https://epulz.io/heartbeat/abc123xyz.
  3. Vo svojom cron jobe na konci úspešného behu zavoláte túto URL (HTTP GET alebo POST).
  4. Ak ping nepríde v očakávanom čase (+ grace perióda), monitoring vás upozorní.

Praktický príklad: heartbeat z cron jobu

# /etc/crontab
0 3 * * * www-data /usr/local/bin/backup.sh && curl -fsS -m 10 \
  https://epulz.io/heartbeat/abc123xyz > /dev/null

Kľúčový je operátor &&: heartbeat sa odošle iba vtedy, keď backup.sh skončí s exit kódom 0. Ak skript zlyhá, ping nepríde a vy do hodiny dostanete upozornenie.

Tip: Pre dôkladnejšie pokrytie pridajte aj "start" heartbeat:

curl -fsS -m 10 https://epulz.io/heartbeat/backup-start-xyz > /dev/null
/usr/local/bin/backup.sh && \
  curl -fsS -m 10 https://epulz.io/heartbeat/backup-done-xyz > /dev/null

Monitoring potom rozlíši "začal a nedokončil" (skript zamrzol) od "vôbec nezačal" (cron job sa nespustil).

Python: requests + try/except

import os, requests
HEARTBEAT_URL = os.environ["HEARTBEAT_URL"]

def sync_data():
    # ... your logic ...
    pass

try:
    sync_data()
    requests.get(HEARTBEAT_URL, timeout=10)
except Exception as e:
    # Heartbeat sa nepošle - monitoring vás upozorní
    raise

Node.js: async / await

const HEARTBEAT_URL = process.env.HEARTBEAT_URL;

async function nightlyJob() {
  await processInvoices();
  await fetch(HEARTBEAT_URL, { signal: AbortSignal.timeout(10000) });
}

nightlyJob().catch(err => {
  console.error(err);
  process.exit(1);
});

Grace period: koľko času dať pred upozornením

Heartbeat monitor potrebuje istú toleranciu. Cron občas beží dlhšie ako obvykle, sieť má latenciu a NTP synchronizácia môže byť mierne posunutá. Grace period je čas po uplynutí očakávaného intervalu, počas ktorého monitoring ešte čaká, kým spustí upozornenie.

Praktické hodnoty:

  • Hourly cron: interval 60 min + grace 10 min
  • Daily backup (priemerne 20 min): interval 1440 min + grace 60 min
  • Weekly report: interval 10080 min + grace 360 min (6 h)

Príliš tesný grace = falošné upozornenia (false-positive). Príliš voľný = oneskorené upozornenie vo chvíli, keď úloha reálne padne.

Kde heartbeat pattern najviac pomáha

  • Nočné DB backups
  • Synchronizácia s externými API (CRM, accounting, payment)
  • Kalkulácie reportov
  • Cleanup úlohy (mazanie starých session, logov, dočasných súborov)
  • Healthcheck cyklus dlho bežiacich workerov
  • Scheduled emaily, newslettre, fakturácia

Záver

Úlohy na pozadí (background) bývajú často kritickejšie ako samotný web, no zostávajú slepou škvrnou monitoringu. Heartbeat pattern si vyžaduje len päť minút na implementáciu (stačí pridať curl na koniec cron riadku) a poskytuje rovnakú istotu ako uptime monitoring frontendu.

Rýchle pripomenutie: syntax cronu

Väčšina chýb heartbeatu sú v skutočnosti chyby cronu - ping sa nikdy nespustí, lebo bol zlý rozvrh. Päť polí je:

┌── minúta (0-59)
│ ┌── hodina (0-23)
│ │ ┌── deň v mesiaci (1-31)
│ │ │ ┌── mesiac (1-12)
│ │ │ │ ┌── deň v týždni (0-7, 0 aj 7 = nedeľa)
│ │ │ │ │
* * * * *  príkaz
Výraz Spustí sa
*/5 * * * * každých 5 minút
0 * * * * na začiatku každej hodiny
0 3 * * * každý deň o 03:00
0 3 * * 1 každý pondelok o 03:00
30 2 1 * * o 02:30 prvého dňa v mesiaci

Klasická pasca: */5 v poli hodina neznamená "každých 5 hodín od teraz", ale hodiny deliteľné piatimi (0, 5, 10, 15, 20). Ak sa očakávaný interval monitora a reálny rozvrh cronu nezhodujú, dostávate fantómové upozornenia.

Princíp "dead man's switch"

Heartbeat pattern je dead man's switch (poistka mŕtveho muža): alarmom je ticho. Toto obracia bežný spôsob zlyhania. Normálny monitoring môže zlyhať potichu - ak padne samotný monitorovací server, jednoducho prestane posielať upozornenia a vy sa to nikdy nedozviete. Heartbeat je opak: spúšťačom upozornenia je neprítomnosť očakávaného signálu, takže úloha, ktorá prestane bežať úplne (celý server je vypnutý, cron démon zakázaný, stroj bol vyradený a zabudnutý), je presne ten prípad, ktorý zachytí najlepšie.

Mimo cronu: ďalšie plánovače

Vzor je rovnaký bez ohľadu na to, čo úlohu spúšťa: - systemd timers - pridajte curl do reťazca ExecStart alebo do ExecStartPost=. Spárujte OnCalendar= timer so zodpovedajúcim intervalom heartbeatu. - Kubernetes CronJob - posledný krok kontajnera pingne heartbeat URL. Ak pod padne alebo sa vôbec nenaplánuje (zlý node selector, zlyhanie image pull), ping chýba a dostanete upozornenie. - Windows Task Scheduler - ukončite úlohu PowerShell príkazom Invoke-WebRequest -Uri $env:HEARTBEAT_URL -TimeoutSec 10. - CI / plánované pipeline - nočný GitHub Actions alebo GitLab schedule môže ako posledný krok pingnúť heartbeat a potvrdiť, že pipeline zbehol aj prešiel.

Bežné anti-patterny

  • Ping na začiatku, nie na konci. Heartbeat odoslaný pred prácou dokazuje len to, že úloha začala. Dajte ho za prácu, podmienený úspechom (&&), aby pád uprostred behu tiež zadržal ping.
  • Ignorovanie exit kódu. backup.sh; curl ... (bodkočiarka) pošle ping aj keď backup zlyhal. Vždy použite &&.
  • Tiché prehltnutie zlyhaní curl. -fsS spôsobí, že curl pri HTTP chybe zlyhá hlasno, takže logy vašej úlohy ukážu, že heartbeat sa nepodarilo doručiť (sieťový problém na stroji).
  • Jeden heartbeat pre desať úloh. Ak päť cronov zdieľa jednu URL, neviete, ktorý prestal bežať. Dajte každej plánovanej úlohe vlastný heartbeat. Ak pre tú istú službu vystavujete aj HTTP endpoint, spárujte heartbeat s bežným uptime checkom a port checkom na porte workera, aby ste pokryli aj "beží proces" aj "prebehol plánovaný beh".

Konkrétny scenár: tiché zlyhanie backupu

Učebnicový prípad pre heartbeat vyzerá takto. Nočný pg_dump zapisuje na pripojený zväzok. Mesiace to funguje. Potom sa zväzok zaplní, pg_dump skončí s nenulovým kódom, a keďže cron riadok použil obyčajnú bodkočiarku, heartbeat sa aj tak odošle a dashboard zostane zelený. O tri týždne je databáza poškodená a neexistuje použiteľný backup, lebo každý "úspešný" backup odvtedy, čo sa disk zaplnil, bol nulový súbor. Heartbeat pattern toto zachytí už prvú noc, ale len ak je zapojený správne: podmieňte ping cez &&, aby nenulový exit ping zadržal, a zvážte kontrolu výstupu, nielen exit kódu. Backup skript môže skončiť s kódom 0 a aj tak vyprodukovať skrátený súbor. Defenzívnejší riadok overí, že dump nie je triviálny, ešte pred signalizáciou úspechu:

/usr/local/bin/backup.sh && \
  test "$(stat -c%s /backups/db.sql.gz)" -gt 1000000 && \
  curl -fsS -m 10 https://epulz.io/heartbeat/abc123xyz > /dev/null

Teraz heartbeat dorazí len vtedy, ak skript uspel a zároveň má výsledný súbor cez 1 MB. Čokoľvek menšie a ping sa zadrží, a vy dostanete upozornenie do grace periódy namiesto o tri týždne neskôr.

Začnite monitorovať cron joby

ePulz.io podporuje heartbeat checks s konfigurovateľnou grace periódou. 7 dní zadarmo.

Spustiť monitoring →

Súvisiace

Zdieľať: Odkaz skopírovaný

Vyskúšajte ePulz.io zadarmo - na 7 dní bez potreby kreditnej karty.

Vytvoriť účet