Перейти к содержимому

Уведомления о результатах бэкапа

«Бэкап, который никто не проверяет, — это не бэкап». Простейший способ проверить — каждый раз получать короткое сообщение об успехе и громкое — об ошибке. Если ежедневной «зелёной» нотификации нет, что-то сломалось.

Подойдёт для restic, borg, pg_dump, rsync, tar — чего угодно. Сохраните как /usr/local/bin/notifly-wrap:

#!/usr/bin/env bash
# Использование:
# notifly-wrap "Имя задачи" -- команда для выполнения
set -eu
set -a; source /etc/notifly.env; set +a
NAME="${1:?name required}"; shift
[ "${1:-}" = "--" ] && shift
START=$(date +%s)
HOST=$(hostname -s)
LOG=$(mktemp)
if "$@" >"$LOG" 2>&1; then
DUR=$(( $(date +%s) - START ))
SIZE=$(wc -l <"$LOG")
/usr/local/bin/notifly-send \
"$NAME — OK ($HOST)" \
"Длительность: ${DUR}s
Строк лога: $SIZE
Хост: $HOST" 3
RC=0
else
RC=$?
DUR=$(( $(date +%s) - START ))
TAIL=$(tail -c 1500 "$LOG")
/usr/local/bin/notifly-send \
"$NAME — FAIL (rc=$RC) — $HOST" \
"Длительность: ${DUR}s
Код: $RC
Последний вывод:
$TAIL" 9
fi
rm -f "$LOG"
exit "$RC"
Окно терминала
sudo chmod +x /usr/local/bin/notifly-wrap

/etc/cron.d/notifly-pg-backup:

SHELL=/bin/bash
0 3 * * * postgres /usr/local/bin/notifly-wrap "pg_dump app" -- \
bash -c 'pg_dump -Fc app | gzip > /var/backups/pg/app-$(date +\%F).sql.gz'

Каждое утро в 03:00 вы получите либо «✅ pg_dump app — OK», либо «❌ pg_dump app — FAIL» с хвостом stderr.

0 4 * * * root /usr/local/bin/notifly-wrap "restic backup /etc /home /srv" -- \
/usr/local/bin/restic -r s3:s3.example.com/bucket backup /etc /home /srv
30 2 * * * root /usr/local/bin/notifly-wrap "rsync /var/www → backup-host" -- \
rsync -aHAX --delete /var/www/ backup@backup-host:/data/www/

«Канарейка»: сообщение, если бэкап вообще не запускался

Заголовок раздела ««Канарейка»: сообщение, если бэкап вообще не запускался»

Если бэкап-скрипт сам упал и нотификация не отправилась, вы об этом не узнаете. Решение — отдельный «канарейка-таймер», который раз в день проверяет, есть ли свежий файл бэкапа:

/usr/local/bin/notifly-backup-canary:

#!/usr/bin/env bash
set -eu
set -a; source /etc/notifly.env; set +a
DIR=/var/backups/pg
LATEST=$(ls -t "$DIR"/*.sql.gz 2>/dev/null | head -1 || true)
NOW=$(date +%s)
if [ -z "$LATEST" ]; then
/usr/local/bin/notifly-send \
"🚨 Нет ни одного бэкапа в $DIR" \
"Канарейка не нашла файлов бэкапа на $(hostname -s)." 10
exit 1
fi
AGE=$(( NOW - $(stat -c %Y "$LATEST") ))
if [ "$AGE" -gt 90000 ]; then # > 25 часов
/usr/local/bin/notifly-send \
"🚨 Старый бэкап на $(hostname -s)" \
"Последний файл: $(basename "$LATEST")
Возраст: $((AGE/3600))ч." 10
fi

Запускайте через cron в 11:00 — после ночного окна:

0 11 * * * root /usr/local/bin/notifly-backup-canary
  • Каждый день видна «жизнь» бэкапа. Зелёная нотификация = вы знаете, что система жива.
  • При ошибке сразу видно причину — последние 1500 байт stderr идут в тело сообщения.
  • Канарейка ловит «тихие» сбои: даже если основной скрипт не запустился, отдельный таймер всё равно прокричит.
  • Хранить размер бэкапа в сообщении и предупреждать, если он внезапно стал меньше или больше обычного на >50 %.
  • Заворачивать туда же pg_verifybackup или restic check — чтобы «зелёным» считался только проверенный бэкап.