O trabalho do Logrotate é mover (renomear) e compactar arquivos. Você o configurou nesse caso para renomear e compactar os arquivos de log do Rails e criar novos com os nomes originais.
Os nomes dos arquivos são uma maneira de encontrar um arquivo, mas o arquivo real é apenas algum espaço no disco. Um arquivo pode ter vários nomes (hard links) ou nenhum nome (você pode rm
de um arquivo que está aberto, mas ainda ocupa espaço no disco desde que o arquivo esteja aberto em algum processo).
O problema que você parece ter aqui é que o aplicativo Rails já tem o arquivo aberto quando é renomeado. O criador de logs do Rails não percebe a mudança de nome, porque usou o nome uma vez para abrir o arquivo e, em seguida, parou completamente de se importar com seu nome. O logger só tem um identificador no arquivo aberto.
Você tem que convencê-lo a fechar e reabrir os arquivos de log, usando seus nomes novamente, o que significa que ele começa a escrever nos novos arquivos vazios que agora têm o nome que os antigos costumavam ter.
Se você der uma olhada em /etc/logrotate.d
, verá muitos exemplos disso, dependendo do que você instalou.
Por exemplo, o rsyslog tem:
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
stunnel tem:
postrotate
/etc/init.d/stunnel4 reopen-logs > /dev/null
endscript
Estes são scripts para informar ao processo relevante que o arquivo precisa ser reaberto. O mecanismo específico depende do programa, mas o que isso tende a ser feito é enviar um HUP
(ou às vezes USR1
) (veja man 7 signal
), que processos de longa execução tomam como instruções para fechar e reabrir arquivos de log.
No caso do Rails, a maneira de fazer isso varia dependendo do logger que você está usando. Acabei de ver alguns conselhos sugerindo que você deve usar copytruncate
, que é basicamente uma "opção de fraude" no logrotate, dizendo para copiar manualmente o conteúdo e esvaziar o arquivo, em vez de movê-lo e criar um novo. (veja man logrotate.conf
). Isso é usado em vez de create
da seguinte forma:
/home/rails/myapp/log/*.log {
daily
missingok
compress
notifempty
rotate 12
copytruncate
delaycompress
missingok
su rails rails
}
Esta não é uma ótima solução, pois é literalmente copiar o arquivo inteiro (para criar um instantâneo dele como está) antes de excluir seu conteúdo, o que é bastante ineficiente.
No entanto, se você estiver usando o Unicorn para rodar seu aplicativo (que multiplexa as solicitações em vários processos de trabalho do Rails idênticos), suporta o sinal USR1 como normal (matando e substituindo todos os trabalhadores, efetivamente fazendo com que eles reabram os arquivos) e você pode simplesmente enviá-lo em um postrotate usando pkill
ou similar, talvez assim:
/home/rails/myapp/log/*.log {
daily
missingok
compress
notifempty
rotate 12
create
delaycompress
missingok
su rails rails
postrotate
pkill -USR1 -u rails unicorn
endscript
}
pkill
é uma ferramenta para pesquisar processos em execução e enviá-los sinais, para que encontre tudo com o nome unicorn
executando como o usuário rails
e envie o sinal USR1
que informa abra os arquivos de log. (Os exemplos que eu dei dos pacotes do Ubuntu ' /etc/logrotate.d
arquivos estão realmente fazendo a mesma coisa, mas esses serviços têm a busca escondida em funções em seus scripts /etc/init.d
.)
Tenho certeza que haverá uma maneira de configurar um postrotate
sensível para qualquer configuração do Rails que você tenha (no pior e mais fácil caso, apenas reinicie), mas espero que isso explique o lado do Ubuntu das coisas de qualquer maneira ...