Push-Benachrichtigungen für Cronjobs
Cron schweigt, wenn ein Job fehlschlägt. Eingebaut ist nur MAILTO, und das mailt dir die Ausgabe jedes Jobs, der irgendetwas ausgibt. Solche Mails liest man bald nicht mehr. Meist willst du das Gegenteil: nichts, solange alles klappt, und einen Push aufs Handy, sobald der Job zum ersten Mal scheitert.
Diese Anleitung erledigt das mit dem Befehl honk-me. Du brauchst fünf Minuten, und es klappt mit jedem Job: Datenbank-Backup, Sync-Skript oder artisan-Befehl.
Voraussetzungen
- Ein Honk-Konto und ein Projekt. Honk gibt es vorerst nur auf Einladung. Noch kein Konto? Dann kannst du Zugang anfragen.
- Ein Ingest-Schlüssel für das Projekt: Öffne in der Web-App das Projekt und erstelle unter Schlüssel einen neuen. Er hat die Form
honk_…und wird nur einmal angezeigt. - Die
honk-me-CLI auf dem Rechner, auf dem Cron läuft. Sie besteht aus einem einzigen Binary:go install github.com/honk-me/honk-go/cmd/honk-me@latest, oder du lädst es von der Releases-Seite herunter. Ohne CLI geht es auch: Die cURL-Variante steht am Ende.
1. Cron den Schlüssel mitgeben
Cron startet Jobs in einer fast leeren Umgebung. Setz die beiden Variablen deshalb ganz oben in die Crontab. Mit crontab -e bearbeitest du eine Datei, die nur dein Benutzer lesen kann:
# crontab -e (the file is readable by your user only)
HONK_URL=https://honk-me.app
HONK_KEY=honk_…Für den Schlüssel hat die CLI bewusst kein Flag. So taucht er nie in ps oder in deinem Shell-Verlauf auf.
2. Nur bei Fehlern alarmieren
Häng || honk-me problem … an den Job an. Die Shell führt das nur aus, wenn der Job mit einem Fehler endet, und $? enthält dann noch seinen Exit-Code:
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 $?"Der --group-key sorgt dafür, dass dein Handy ruhig bleibt. Jeder Fehlschlag des Backups landet in derselben Gruppe, db/backup. Der erste wird sofort gepusht. Schlägt der Job in derselben Episode weiter fehl, schickt Honk statt neuer Alarme höchstens alle 5 Minuten ein ruhiges Update. Im Posteingang steht dann eine einzige Zeile mit Zähler.
Ein Detail, über das jeder einmal stolpert: In einer Crontab bedeutet % „neue Zeile“. Enthält dein Befehl ein date +%F, schreib es als date +\%F.
3. Auch erfahren, wenn es wieder läuft
Ein Problem bleibt offen, bis es jemand schließt. Honk schließt es, sobald für denselben Gruppenschlüssel eine Entwarnung eintrifft, und pusht auch diese. Dann weißt du, dass du dich nicht mehr kümmern musst.
Schick aber nicht nach jedem erfolgreichen Lauf eine Entwarnung. Auch ohne offenes Problem eröffnet sie eine Episode mit dem Status „Behoben“ und löst eine Mitteilung aus. Du bekämst sonst jede Nacht einen Push. Schick sie deshalb nur beim ersten Erfolg nach einem Fehlschlag. Dieser Wrapper merkt sich dafür das letzte Ergebnis in einer kleinen Statusdatei:
#!/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"Speichere ihn als /usr/local/bin/honk-cron, mach ihn mit chmod +x ausführbar und setz ihn vor einen beliebigen Job, mit dem Gruppenschlüssel als erstem 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:syncEr schickt die letzten 6.000 Bytes der Ausgabe als Nachricht mit. Push und Posteingang zeigen also den tatsächlichen Fehler, nicht nur „fehlgeschlagen“. Er gibt immer den Exit-Code des Jobs zurück, und dank || true macht ein Problem beim Senden nie aus einem guten Lauf einen fehlgeschlagenen.
Ohne die CLI: cURL
curl ist auf fast jedem Server installiert. Hier derselbe Alarm als einzelne Crontab-Zeile, mit ausgeschriebenem JSON:
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\"}"Die CLI kann mehr als diese Zeile: Wiederholungen mit demselben Idempotency-Key, ein Gesamtzeitlimit und Exit-Codes, auf die du reagieren kannst.
Was die Exit-Codes bedeuten
honk-me endet mit 0, wenn Honk das Ereignis angenommen hat (oder schon kannte), mit 4 bei einem falschen oder widerrufenen Schlüssel, mit 5, wenn ein Kontingent aufgebraucht ist, und mit 7, wenn Netzwerk oder Server auch nach allen Wiederholungen versagt haben. Die CLI-Seite listet alle auf. In Cron gehört meist ein || true hinter den Befehl.
Was Honk ergänzt
MAILTO schickt eine Mail für jeden Lauf, der etwas ausgibt. Honk schickt einen Push für jedes neue Problem und bündelt die Wiederholungen samt Ausgabe in einer Gruppe. Es sagt dir, wenn wieder alles läuft, und sammelt alles in einem Posteingang, neben deinen anderen Jobs und Servern. Wie laut die Nacht wird, bestimmen Ruhezeiten und Zusammenfassung.
Honk gibt es vorerst nur auf Einladung: Zugang anfragen. Alles in dieser Anleitung funktioniert schon im Free-Tarif.