Notificări push de la un cron job
Cron nu te anunță când un job eșuează. Singura alertă inclusă e MAILTO, care îți trimite pe email tot ce afișează fiecare job care afișează ceva, iar emailurile astea ajungi repede să nu le mai citești. De obicei vrei exact invers: nimic cât timp jobul merge și o notificare pe telefon prima dată când nu mai merge.
Ghidul face asta cu comanda honk-me. Durează cinci minute și merge cu orice job: un backup al bazei de date, un script de sincronizare, o comandă artisan.
Înainte să începi
- Un cont Honk și un proiect. Deocamdată, Honk e disponibil doar pe bază de invitație; dacă nu ai cont, cere acces.
- O cheie API pentru proiect: în aplicația web, deschide proiectul, apoi Chei, și creează una. Arată ca
honk_…și se afișează o singură dată. - CLI-ul
honk-mepe mașina care rulează cron. E un singur binar:go install github.com/honk-me/honk-go/cmd/honk-me@latestsau îl descarci de pe pagina Releases. Nu ai CLI-ul? Varianta cu cURL e la final.
1. Dă-i lui cron cheia
Cron rulează joburile cu un mediu aproape gol, așa că pune cele două variabile la începutul crontabului. crontab -e editează un fișier pe care îl poate citi doar utilizatorul tău:
# crontab -e (the file is readable by your user only)
HONK_URL=https://honk-me.app
HONK_KEY=honk_…CLI-ul nu are, intenționat, un flag pentru cheie, ca ea să nu apară niciodată în ps sau în istoricul shellului.
2. Alertă doar când jobul eșuează
Adaugă || honk-me problem … după job. Shellul rulează comanda doar când jobul se termină cu eroare, iar $? păstrează în continuare codul de ieșire al jobului:
0 3 * * * pg_dump app > /backup/app.sql || honk-me problem --group-key db/backup --source "$(hostname)" --title "Backup failed" --message "pg_dump exited with $?"Telefonul rămâne liniștit datorită lui --group-key. Toate eșecurile backupului ajung în același grup, db/backup. Primul te anunță imediat; dacă jobul eșuează în continuare în același episod, Honk trimite cel mult o actualizare discretă la 5 minute în loc de o alarmă nouă, iar în inbox vezi un singur rând, cu un contor.
Un detaliu care îl prinde pe toată lumea măcar o dată: într-un crontab, % înseamnă „rând nou”. Dacă în comandă ai date +%F, scrie date +\%F.
3. Află și când merge din nou
O problemă rămâne deschisă până când ceva o închide. Honk o închide când aceeași cheie de grup raportează o revenire și te anunță și despre ea, ca să știi că te poți liniști.
Nu trimite însă o revenire după fiecare rulare reușită. O revenire fără o problemă deschisă tot deschide un episod „revenit” și te anunță, așa că ai primi o notificare în fiecare noapte. Trimite-o doar la primul succes după un eșec. Wrapperul de mai jos ține minte ultimul rezultat într-un mic fișier de stare:
#!/usr/bin/env bash
# honk-cron: run a command; honk when it fails, and once when it works again.
# usage: honk-cron <group-key> <command> [args…]
set -uo pipefail
key=$1; shift
state="${XDG_STATE_HOME:-$HOME/.local/state}/honk-cron/${key//\//_}.failed"
mkdir -p "$(dirname "$state")"
out=$(mktemp); trap 'rm -f "$out"' EXIT
"$@" >"$out" 2>&1
code=$?
if [ "$code" -ne 0 ]; then
# the end of the output is usually the useful part; a message holds up to 8192 bytes
tail -c 6000 "$out" | honk-me problem --group-key "$key" --source "$(hostname)" \
--title "$key failed (exit $code)" --message - || true
touch "$state"
elif [ -e "$state" ]; then
honk-me recovery --group-key "$key" --source "$(hostname)" \
--title "$key works again" --message "Exit code 0 after a failure." || true
rm -f "$state"
fi
exit "$code"Salvează-l ca /usr/local/bin/honk-cron, fă-l executabil cu chmod +x și pune-l în fața oricărui job, cu cheia de grup ca prim argument:
0 3 * * * /usr/local/bin/honk-cron db/backup pg_dump -f /backup/app.sql app
*/15 * * * * /usr/local/bin/honk-cron sync/invoices php /srv/app/artisan invoices:syncMesajul conține ultimii 6.000 de octeți din ce a afișat jobul, așa că în notificare și în inbox vezi eroarea propriu-zisă, nu doar „eșuat”. Wrapperul se termină mereu cu codul de ieșire al jobului, iar || true face ca o problemă la trimiterea notificării să nu poată transforma niciodată o rulare reușită într-una eșuată.
Fără CLI: cURL
curl există pe aproape orice server. Iată aceeași alertă într-o singură linie de crontab, cu JSON-ul scris complet:
0 3 * * * pg_dump app > /backup/app.sql || curl -sS --max-time 10 --retry 3 "$HONK_URL/v1/messages" -H "Authorization: Bearer $HONK_KEY" -H "Content-Type: application/json" -d "{\"title\":\"Backup failed\",\"message\":\"pg_dump exited with $?\",\"severity\":\"long\",\"event_type\":\"problem\",\"group_key\":\"db/backup\"}"CLI-ul îți dă ce îi lipsește acestei linii: reîncercări cu aceeași cheie de idempotență, o limită totală de timp și coduri de ieșire după care te poți ghida.
Ce înseamnă codurile de ieșire
honk-me se termină cu 0 când Honk a acceptat evenimentul (sau îl avea deja), cu 4 când cheia e greșită sau revocată, cu 5 când ai epuizat o cotă și cu 7 când rețeaua sau serverul a cedat după toate reîncercările. Lista completă e pe pagina CLI. În cron, de obicei vrei || true după comandă.
Ce aduce Honk în plus față de cron
Cu MAILTO primești câte un email pentru fiecare rulare care afișează ceva. Honk îți trimite o notificare pentru fiecare problemă nouă, adună repetările într-un grup, împreună cu ce au afișat, te anunță când jobul își revine și ține totul într-un singur inbox, lângă celelalte joburi și servere. Cât de zgomotoase îți sunt nopțile hotărăsc orele de liniște și rezumatul.
Deocamdată, Honk e disponibil doar pe bază de invitație: cere acces. Tot ce face acest ghid merge și pe planul Free.