Sumário
- As três formas como um backup falha
- Passo 1 — Crie um canal capaz de chamar sua atenção
- Passo 2 — Detecte falhas com um script wrapper
- borg e borgmatic
- Passo 3 — Detecte o backup que nunca rodou
- Passo 4 — Confira se o backup está atual e é restaurável
- Passo 5 — Tocar só quando importa
- Perguntas frequentes
- Como sou avisado quando um backup falha?
- Em quais códigos de saída do restic devo alertar?
- Como sei se um backup parou de rodar em silêncio?
- Um código de saída de sucesso basta para confiar num backup?
- Posso receber uma ligação em vez de um e-mail?
- Fechando
- Artigos relacionados
A maioria das pessoas descobre que o backup estava quebrado no dia em que precisa dele. O job terminou com erro três semanas atrás, ninguém leu o log, e o snapshot mais recente é anterior ao erro que você está tentando desfazer.
A solução não é uma ferramenta de backup melhor. É garantir que um problema de backup chegue a um humano na mesma hora em que acontece. Este guia mostra como fazer isso com restic e borg (e qualquer coisa que rode a partir de um shell), cobrindo as três formas como os backups realmente falham, com scripts que você pode copiar. O passo final manda o alerta para o seu celular pelo Echobell, para que um backup quebrado toque em vez de ficar parado numa caixa de e-mail.
As três formas como um backup falha
Monitorar só a primeira é o erro mais comum.
- Roda e falha. Repositório bloqueado, disco cheio, senha errada, queda de rede. A ferramenta sai com código diferente de zero.
- Roda e dá certo pela metade. O restic sai com o código
3quando um snapshot foi criado mas alguns arquivos não puderam ser lidos. O borg sai com1em caso de avisos. Os dois são fáceis de ignorar, e ambos podem esconder um problema de permissão que pula em silêncio o seu diretório mais importante. - Nunca roda. O servidor estava desligado, o timer foi desativado, o crontab foi sobrescrito. Não há erro porque não há processo. É essa a falha que mais machuca.
Cada uma precisa de um detector diferente, então vamos construir os três.
Passo 1 — Crie um canal capaz de chamar sua atenção
No Echobell, crie um canal chamado backups e defina o tipo de notificação como Ligação para os jobs que importam. Copie a URL do webhook:
https://hook.echobell.one/t/<channel-token>
Dê a ele templates que façam sentido meio dormindo, usando os campos que vamos enviar abaixo:
Título: Backup {{status}} em {{host}}
Corpo: {{job}}: {{detail}}
Veja a referência de templates para a sintaxe.
Passo 2 — Detecte falhas com um script wrapper
Um pequeno wrapper transforma códigos de saída em alertas. Salve como /usr/local/bin/backup-run:
#!/usr/bin/env bash
set -uo pipefail
HOOK="https://hook.echobell.one/t/<channel-token>"
JOB="nightly-restic"
alert() {
curl -fsS -m 10 -X POST "$HOOK" \
-H "Content-Type: application/json" \
-d "{\"job\":\"$JOB\",\"host\":\"$(hostname)\",\"status\":\"$1\",\"detail\":\"$2\"}" || true
}
restic backup /srv /etc --exclude-caches
code=$?
case $code in
0) ;; # sucesso: ficar em silêncio
3) alert "incomplete" "Snapshot saved, but some files were unreadable" ;;
11) alert "locked" "Repository is locked by another process" ;;
12) alert "auth-failed" "Wrong repository password" ;;
*) alert "failed" "restic exited with code $code" ;;
esac
exit $code
Por que os detalhes importam:
- O
set -enão é usado de propósito, para que o script ainda chegue ao alerta depois que o restic falhar. - O
|| truenocurlfaz com que um webhook inacessível nunca esconda o código de saída real. - O
-m 10impede que uma chamada de rede travada bloqueie a próxima execução agendada.
Os códigos de saída do restic usados acima estão documentados no manual do restic: 0 sucesso, 1 erro fatal, 3 snapshot criado mas alguns arquivos de origem ilegíveis, 10 o repositório não existe, 11 falha ao bloquear, 12 senha errada. Confirme com restic version na sua própria máquina, já que códigos foram sendo adicionados com o tempo.
borg e borgmatic
O borg retorna 0 para sucesso, 1 para avisos e 2 ou mais para erros. Um arquivo que muda durante o backup gera 1, algo rotineiro em diretórios de log, então uma abordagem comum é ligar só a partir de 2 e mandar uma notificação discreta para 1:
borg create --stats ::'{hostname}-{now}' /srv /etc
code=$?
if [ "$code" -ge 2 ]; then
alert "failed" "borg exited with code $code"
elif [ "$code" -eq 1 ]; then
alert "warning" "borg finished with warnings"
fi
Se você usa o borgmatic, o hook on_error dele executa um comando quando o próprio borgmatic encontra um erro, que é o lugar natural para o mesmo curl. Note o limite que a própria documentação do borgmatic admite: se o borgmatic nunca roda, o on_error nunca dispara. Essa é a falha número três, e ela precisa do Passo 3.
Passo 3 — Detecte o backup que nunca rodou
Um wrapper só consegue relatar uma execução que aconteceu. Para pegar o silêncio, inverta a lógica: o backup envia um ping a um monitor quando dá certo, e o monitor avisa você quando o ping atrasa. Isso se chama dead man's switch.
O Healthchecks.io (hospedado ou auto-hospedado) faz exatamente isso:
- Crie um check com o agendamento
0 3 * * *e um tempo de tolerância de uma ou duas horas. - Adicione o ping dele ao final do seu job, para que só dispare em caso de sucesso.
- Nas integrações do check, adicione um Webhook apontando para a URL do seu canal do Echobell.
O ping vai no final do wrapper:
# no backup-run, logo antes do `exit $code` final; só faz ping em caso de sucesso
if [ $code -eq 0 ]; then
curl -fsS -m 10 --retry 3 -o /dev/null https://hc-ping.com/<your-uuid>
fi
O Healthchecks também aceita as variantes de ping /start e /fail e pode receber o código de saída na URL, então um único check também pega jobs que travam. O resultado: um servidor morto, um timer desativado e uma linha de crontab apagada produzem o mesmo desfecho, um telefone tocando. Para o padrão geral e outros monitores, veja alertas de falha de cron jobs.
Passo 4 — Confira se o backup está atual e é restaurável
Um backup pode rodar no horário, sair com 0 e ainda assim ser inútil, por exemplo quando você está fazendo backup de um diretório vazio porque uma montagem falhou. Adicione duas checagens baratas num job diário separado:
Idade do snapshot. Alerte se o snapshot mais recente for mais velho do que o esperado:
latest=$(restic snapshots --latest 1 --json | jq -r '.[0].time')
age_h=$(( ( $(date +%s) - $(date -d "$latest" +%s) ) / 3600 ))
if [ "$age_h" -gt 30 ]; then
alert "stale" "Newest snapshot is ${age_h}h old"
fi
Integridade do repositório. O restic check verifica a estrutura do repositório. Rode-o semanalmente; em repositórios grandes, restic check --read-data-subset=5% amostra os dados sem ler tudo. Alerte em caso de saída diferente de zero.
Nenhuma das duas substitui um teste de restauração de verdade. Uma vez por trimestre, restaure para um diretório temporário um arquivo que você consiga verificar. É o único teste que prova que o backup funciona.
Passo 5 — Tocar só quando importa
Se todo aviso te ligar, você vai silenciar o canal, e aí ele não vai tocar para o que realmente conta. Use as condições do Echobell para separar níveis em um mesmo canal:
status == "failed" || status == "stale" || status == "auth-failed"
Mande incomplete e warning para um segundo canal Urgente (Time Sensitive) ou normal, para que apareçam na tela bloqueada sem tocar. Acrescente uma janela de horário se quiser que as falhas durante o dia sejam discretas, usando as variáveis UTC descritas na referência de condições.
Perguntas frequentes
Como sou avisado quando um backup falha?
Envolva o comando de backup, leia o código de saída e envie um webhook em qualquer código diferente de zero. Adicione um dead man's switch como o Healthchecks.io para também saber das execuções que nunca começaram.
Em quais códigos de saída do restic devo alertar?
Alerte com força em 1, 10, 11 e 12, que indicam uma falha real. Trate o 3 (snapshot criado mas alguns arquivos ilegíveis) como um aviso a investigar, pois ele pode esconder um problema de permissão.
Como sei se um backup parou de rodar em silêncio?
Use um heartbeat: o job envia um ping a um monitor em caso de sucesso, e o monitor avisa quando o ping atrasa. Um hook de erro não consegue pegar isso, porque nada roda para gerar o erro.
Um código de saída de sucesso basta para confiar num backup?
Não. Significa que a ferramenta terminou, não que os dados estejam completos ou sejam restauráveis. Confira a idade dos snapshots, rode verificações de integridade periódicas e teste uma restauração com regularidade.
Posso receber uma ligação em vez de um e-mail?
Pode. E-mail é fácil de perder. Um canal de ligação no Echobell se comporta como uma chamada recebida e atravessa o modo Foco do iOS, então um backup que falhou às 03:00 é notado.
Fechando
Três detectores cobrem os três modos de falha: um wrapper de códigos de saída para as execuções que falham, uma checagem de atualidade para as que dão certo sem servir para nada, e um heartbeat para as que nunca acontecem. Encaminhe-os para um canal de ligação, mantenha os avisos num mais discreto, e um backup quebrado vira um conserto de cinco minutos em vez de um fim de semana perdido.
Baixe o Echobell para iPhone ou pegue no Google Play, crie o canal backups e rode o wrapper uma vez com uma senha propositalmente errada para ouvi-lo tocar.