Notificaciones push desde una tarea cron
Cuando una tarea falla, cron no dice nada. Su único aviso es MAILTO, que te manda por correo la salida de cualquier tarea que imprima algo, y esos correos se dejan de leer enseguida. Lo que sueles querer es justo lo contrario: silencio mientras la tarea funciona y un aviso en el teléfono la primera vez que falla.
Esta guía lo resuelve con el comando honk-me. Lleva cinco minutos y sirve para cualquier tarea: una copia de seguridad de la base de datos, un script de sincronización o un comando de artisan.
Antes de empezar
- Una cuenta de Honk y un proyecto. Por ahora, Honk funciona solo con invitación; solicita acceso si aún no tienes cuenta.
- Una clave de ingesta del proyecto: en la app web, abre el proyecto, entra en Claves y crea una. Empieza por
honk_…y solo se muestra una vez. - La CLI
honk-meen la máquina donde se ejecuta cron. Es un único binario: instálalo congo install github.com/honk-me/honk-go/cmd/honk-me@latesto descárgalo de la página de releases. ¿Prefieres no usar la CLI? Al final tienes la versión con cURL.
1. Dale la clave a cron
Cron ejecuta las tareas con un entorno casi vacío, así que pon las dos variables al principio del crontab. crontab -e edita un archivo que solo tu usuario puede leer:
# crontab -e (the file is readable by your user only)
HONK_URL=https://honk-me.app
HONK_KEY=honk_…La CLI no acepta la clave como opción, y es a propósito: así nunca aparece en ps ni en el historial de la shell.
2. Avisa solo cuando la tarea falla
Añade || honk-me problem … detrás de la tarea. La shell solo lo ejecuta si la tarea termina con error, y $? conserva su código de salida:
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 $?"--group-key es lo que mantiene el teléfono en calma. Todos los fallos de la copia de seguridad van al mismo grupo, db/backup. El primero te avisa al momento. Si la tarea sigue fallando dentro del mismo episodio, Honk no lanza una alarma nueva: envía como mucho una actualización discreta cada 5 minutos, y la bandeja de entrada muestra una sola fila con el recuento.
Un detalle con el que todo el mundo tropieza alguna vez: en un crontab, % significa «salto de línea». Si tu comando contiene un date +%F, escríbelo como date +\%F.
3. Que también te avise cuando vuelva a funcionar
Un problema sigue abierto hasta que algo lo cierra. Honk lo cierra cuando llega una recuperación con la misma clave de grupo, y también te lo notifica: así sabes que ya puedes dejar de preocuparte.
Eso sí, no envíes una recuperación tras cada ejecución correcta. Aunque no haya ningún problema abierto, una recuperación abre un episodio «recuperado» y avisa, así que recibirías un aviso cada noche. Envíala solo con el primer éxito después de un fallo. Este script envuelve la tarea y guarda el último resultado en un pequeño archivo de estado:
#!/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"Guárdalo como /usr/local/bin/honk-cron, hazlo ejecutable con chmod +x y ponlo delante de cualquier tarea, con la clave de grupo en primer lugar:
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:syncUsa como mensaje los últimos 6000 bytes de la salida de la tarea, así que la notificación y la bandeja de entrada muestran el error real, no solo que algo falló. Siempre termina con el código de salida de la propia tarea, y || true impide que un fallo al notificar convierta una ejecución correcta en fallida.
Sin la CLI: cURL
curl está en casi todos los servidores. Esta es la misma alerta en una línea de crontab, con el JSON escrito a mano:
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\"}"La CLI añade lo que esta línea no tiene: reintentos con una misma clave de idempotencia, un tiempo límite total y códigos de salida que puedes comprobar.
Qué significan los códigos de salida
honk-me devuelve 0 si Honk aceptó el evento (o ya lo tenía), 4 si la clave es incorrecta o está revocada, 5 si se agotó una cuota y 7 si la red o el servidor fallaron tras todos los reintentos. La página de la CLI los recoge todos. En cron, lo normal es añadir || true detrás del comando.
Qué añade Honk a cron
MAILTO te manda un correo por cada ejecución que hace ruido. Honk te manda una notificación por cada problema nuevo, reúne las repeticiones en un grupo con su salida, te avisa cuando todo se recupera y lo deja en una sola bandeja de entrada, junto a tus otras tareas y servidores. Con las horas de silencio y el resumen, tú decides cuánto ruido quieres por la noche.
Por ahora, Honk funciona solo con invitación: solicita acceso. Todo lo que explica esta guía funciona con el plan Free.