Tratamento de logs, com buffer para truncar sem perda de informação

Limpeza de logs com BUFFER para TRUNCAR sem perda de informação


versão candidata:
https://github.com/guprobr/shell-foo/blob/main/logtruncate.sh

Esse script estou fazendo com a proposta de limpar/rodar logs usando um buffer para truncar o arquivo sem perda de informação, liberando espaço ou organizando logs sem necessidade de stop/start na aplicação. NOTA: Ainda não testado pormenorizadamente em ambiente de produção.

# Inicia o buffer dos logs atuais
tail -f mega_log > temp_log &
# Guarda o PID do processo tail
TAIL_PID=$!

# Copia o arquivo atual para um arquivo temporário
cp mega_log mega_log_copy
# Trunca o arquivo original
cat /dev/null > mega_log

# Mata o processo tail
kill $TAIL_PID

# Concatena os logs adicionais ao final do arquivo copiado
cat temp_log >> mega_log_copy
# Comprime o arquivo copiado
gzip mega_log_copy
# Renomeia o arquivo comprimido
mv mega_log_copy.gz mega_log-20250307.gz
# Remove o arquivo temporário!!
rm temp_log

# Valida se continua escrevendo no arquivo truncado
tail -f mega_log

A idéia da coisa é manter o descriptor do arquivo aberto para aplicação poder continuar escrevendo no arquivo, sem necessidade de stop/start, por isso o truncamento e não mover ou deletar. Só que para evitar perda de logs durante o momento da cópia de bkp, executada antes do truncamento para não se perder os logs já gerados, criamos um buffer em que se escrevem os logs gerados no instante em que se ainda copia os anteriores. Ao final se concatena o buffer a cópia de bkp, e compacta o resultado para arquivar e rotacionar.

Possíveis Problemas e Melhorias

  1. Race Condition no Truncamento
    • O tail -f pode perder alguns logs se o truncamento acontecer exatamente quando a aplicação estiver escrevendo.
    • Solução: tail -F em vez de tail -f, pois o -F trata melhor casos onde o arquivo é recriado ou truncado.
  2. Execução de kill $TAIL_PID
    • Se o script for interrompido antes do kill, o tail pode continuar rodando como processo órfão.
    • Solução: Usar trap para garantir que o kill será executado ao sair.
  3. Remoção do Arquivo Temporário temp_log
    • Caso o script seja interrompido antes do cat temp_log >> mega_log_copy, os logs podem ser perdidos.
    • Solução: Executar a concatenação antes do kill $TAIL_PID, garantindo que tudo foi salvo.
  4. Uso de /dev/null para truncar o log
    • Funciona, mas uma abordagem mais explícita seria truncate -s 0 mega_log.