Configurando o registro para um script de backup remoto

3

Então eu escrevi um pequeno script que estou planejando executar por meio de um cron job diariamente para empacotar os arquivos do meu site e enviá-los para um local remoto. Eu também pretendo incorporar DB dumps, mas eu não cheguei tão longe ainda.

Meu problema hoje, porém, é que estou incerto sobre como registrar a saída de cada comando em busca de erros, avisos ou outras informações pertinentes que o comando possa gerar. Eu também gostaria de instalar algum tipo de segurança contra falhas, por isso, se algo der errado, o script irá parar em suas trilhas e me notificar via e-mail ou algo assim. Ok, a coisa do email não é tão crítica, mas seria legal.

Alguém tem alguma ideia para isso? Aqui está o que eu tenho até agora.

A propósito, ambos os servidores são o CentOS 6.2 executando LAMP padrão.

#!/bin/sh

#################################
### Set Vars
#################################
THEDATE='date +%m%d%y%H%M'

#################################
### Create Archives
#################################
tar -cf /root/backups/files/server_BAK_${THEDATE}.tar -C / var/www/vhosts
gzip /root/backups/files/server_BAK_${THEDATE}.tar

#################################
### Send Data to Remote Server
#################################
scp /root/backups/files/server_BAK_${THEDATE}.tar.gz user@host:/home/bak1/ftp/backups/

#################################
### Remove Data from this Server
#################################
rm -rf /root/backups/files/server_BAK_${THEDATE}.tar.gz
    
por Brian Dainis 02.11.2012 / 07:06

3 respostas

0

Uma resposta pouco desorganizada, mas apenas leia, por favor.

Para fazer com que o seu script pare quando houver algum tipo de erro:

set -e

Isso garantirá que, se qualquer dos seus comandos falhar, o script falhará. Outras boas ideias:

function error_handler() {
   # This will get run when an error is detected
}
trap error_handler ERR

Isso executará o error_handler quando um comando falhar. Você também pode ter um manipulador EXIT para executar o código toda vez que o script sair.

Para capturar todos os resultados do seu script em um arquivo:

exec &> some_log_file

Para também poder ver os comandos que seu script executa no arquivo de log (excelente para solução de problemas):

set -x

Para fazer seu script lançar avisos sobre variáveis indefinidas:

set -u

Para resumir, inicie seu script com:

trap error_handler ERR
exec &> some_log_file
set -eux

Se você estiver executando o script do cron, ele enviará um e-mail se houver alguma saída do seu script. Para receber o e-mail apenas quando houver um problema, coloque um cat some_log_file no manipulador de erros e você está definido.

Atualizar : para responder às suas outras perguntas.

  • Para evitar que um erro quebre o script inteiro, você pode executar o comando em uma instrução if . Como if ! <some command>; then <what do you do if it fails, or possibly nothing>; fi
  • Se você tiver trap error_handler , também precisará definir um function error_handler .
  • O embaralhamento de set -eu e set -eux não é uma má ideia, mas ...
  • ... se você está preocupado com a segurança, você não deve colocar a senha mysql na linha de comando (qualquer um que executar pgrep -lf mysql vai ver). Use um arquivo de opções. E então você não precisa se preocupar com senhas nos arquivos de log.

    option_file='mktemp'
    cat > $option_file <<EOF
    [client]
    password = $DB_PASSWD
    user     = $DB_USER
    EOF
    

    Em seguida, execute mysqldump com --default-extra-path=$option_file . E não esqueça de deletar $option_file quando você não precisar mais dele.

  • Use rsync em vez de scp . Funciona muito melhor para copiar arquivos relativamente grandes.
por 02.11.2012 / 09:33
1

Você pode redirecionar o erro de cada comando para um arquivo específico.

grep da * 2> grep-errors.txt

Isso redireciona erros do grep para o arquivo grep-errors.txt.

grep da * 1>&2

Isso fará com que a saída stderr de um programa seja gravada no mesmo filedescriptor que stdout.

rm -rf * 2>&1 Isso fará com que a saída stderr de um programa seja gravada no mesmo filedescriptor que stdout

rm -f $(find / -name core) &> /dev/null

Isso colocará todas as saídas de um programa em um arquivo. Isso é adequado às vezes para as entradas do cron, se você quiser que um comando passe em absoluto silêncio. Claro que você pode substituir / dev / null com algum arquivo e escrever toda a saída para ele.

Isso é para erros de registro. Eu sei que é simples script de backup, mas você está tentando reinventar a roda mais uma vez. E na minha opinião você deveria checar Bacula. É uma solução bastante grande para fazer backup de apenas um servidor, mas ele fará tudo o que você solicitar em questão. Buckup, notificar etc e muito mais. Você terá uma das melhores soluções de backup. Configurá-lo para apenas um ou poucos servidores é bastante simples e você o fará em poucas horas.

Se você ainda quiser usar o seu script, então você deve redirecionar todos os erros para o stdout depois de adicionar este script ao cron, ele enviará um e-mail para cada saída desse script. Você deve checar apenas o / etc / aliases para entrada de root e escrever seu email lá assim:

root: [email protected]

    
por 02.11.2012 / 07:42
0

Eu fiz algumas atualizações no script. Aqui está o novo. Ainda trabalhando nisso,

EDIT: Então, fiz ainda mais ajustes no script para incorporar um backup iterado dos bancos de dados. Abaixo está a versão mais recente. Eu estou no processo de testá-lo agora.

Minhas novas perguntas são: Eu não quero mostrar senhas para o banco de dados no arquivo de log, então eu configurei o primeiro "set" para "set -eu". Mas eu decidi que quero ver quais comandos estão rodando no script no arquivo de log, então, após a conclusão da iteração e do despejo do banco de dados, eu reconfigurei "set" para "set -eux". Essa boa prática é o que eu fiz? Além disso, como posso mostrar registros de data e hora no arquivo de log?

#/bin/sh

#################################
### Set Vars
#################################
LOCALBAKTMP='/root/backups/files'                            ###~~~PLACE WHERE TMP FILES GO
LOCALBAKLOC='var/www/vhosts'                                 ###~~~DIRECTORY TO BACKUP (NO SLASH IN FRONT)
REMOTEUSR='user'                                             ###~~~USER AT REMOTE SERVER
REMOTEHOST='host'                                            ###~~~REMOTE HOST ADDRESS
REMOTEDEST='/home/bak1/ftp/backups/'                         ###~~~FILE DESTINATION AT REMOTE
LOGDIR='/root/backups/logs/'                                 ###~~~LOCAL BACKUP LOG DIRECTORY
DELLOGSDAYS='30'                                             ###~~~DAYS TO STORE LOG FILES
THEDATE='date +%m%d%y%H%M'                                   ###~~~DATE VARIABLE
DB_BACKUP="/root/backups/files/dbs"                          ###~~~DB BACKUP LOCATION
LOCALDBLOC="root/backups/files/dbs"                          ###~~~DB FILES TO BAK
DB_USER="dbuser"                                             ###~~~DB ROOT USER
DB_PASSWD="dbpassword"                                       ###~~~DB ROOT PASS
HN='hostname | awk -F. '{print $1}''                         ###~~~DO NOT CHANGE

#################################
### Set Logging
#################################
trap error_handler ERR
exec &> ${LOGDIR}bak_${THEDATE}.log
set -eu

#################################
### Dump MySQL
#################################
for db in $(mysql --user=$DB_USER --password=$DB_PASSWD -e 'show databases' -s --skip-column-names|grep -vi information_schema);
do mysqldump --user=$DB_USER --password=$DB_PASSWD --opt $db | gzip > "$DB_BACKUP/mysqldump-$HN-$db-$(date +%Y-%m-%d).sql.gz";
done
#Log commands for the rest of the script
set -eux

#################################
### Create Archives
#################################
tar -cf ${LOCALBAKTMP}/server_BAK_${THEDATE}.tar -C / ${LOCALBAKLOC}
gzip ${LOCALBAKTMP}/server_BAK_${THEDATE}.tar
tar -cf ${LOCALBAKTMP}/db_BAK_${THEDATE}.tar -C / ${LOCALDBLOC}
gzip ${LOCALBAKTMP}/db_BAK_${THEDATE}.tar
tar -cfz full_BAK_${THEDATE}.tar.gz *_BAK_${THEDATE}.tar.gz

#################################
### Send Data to Remote Server
#################################
scp ${LOCALBAKTMP}/full_BAK_${THEDATE}.tar.gz ${REMOTEUSR}@${REMOTEHOST}:${REMOTEDEST}

#################################
### Remove Data from this Server
#################################
rm -f ${LOCALBAKTMP}/*_BAK_${THEDATE}.tar.gz
rm -rf ${DB_BACKUP}/*.sql.gz
find ${LOGDIR}* -mtime +${DELLOGSDAYS} -exec rm {} \;
    
por 02.11.2012 / 22:08