Como continuar redirecionando o stdout para um arquivo depois que o logrotate o move?

21

Eu tenho um script simples que gera vários logs para a tela e canalizo o STDOUT para um arquivo para armazenar os logs. Como esse script está em execução há muito tempo, precisei girar os arquivos de log para que fossem lançados em outros menores e mais gerenciáveis.

O problema que enfrentei foi que, quando o logrotate move o arquivo de log atual para um novo, o arquivo de log recém-criado não é mais preenchido com os logs. Parece que quando o arquivo de log original é removido, seu manipulador de arquivos é perdido e o redirecionamento não funciona mais.

Também encontrei este post que tinha o mesmo problema que eu e afirma que ele pode ser corrigido usando >> em vez de > para redirecionar a saída. Eu testei sua solução, mas não funcionou para mim. Alguém tem alguma idéia de como manter o redirecionamento funcionando?

    
por Mehran 03.07.2014 / 08:23

4 respostas

24

Você deve usar a diretiva copytruncate em sua configuração logrotate para este arquivo de log.

copytruncate Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place

    
por 03.07.2014 / 08:26
5

Como alternativa, você também pode:

  • use o utilitário do registrador em seu script em vez de canalizar, com um recurso dedicado (por exemplo, local5), por exemplo:

    logger -p local5.info -t myscriptname "this is some log data"

  • configure o syslog para gravar este recurso no arquivo de log desejado, exemplo (rsyslog.conf):

    local5.* /var/log/mylogfile

  • configure a regra logrotate para este log.

por 03.07.2014 / 11:37
3

Outra alternativa para a solução Iain é usar um script postrotate para relançar seu script depois que a rotação tiver ocorrido. Isso é feito para muitos daemons (reinicie ou recarregue o daemon), mas sem saber o seu script, não sei se essa solução vai servir ou não (o seu script depende de algum estado gerado há algum tempo atrás?).

Conteúdo de /etc/logrotate.d/your-script-name :

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}
    
por 03.07.2014 / 22:43
-1

Você pode canalizar stdout para "split" (parte do coreutils no linux). Ele permite que você divida o arquivo / stdin em partes com base no tamanho, número de linhas, etc. Depois de obter em pedaços, você pode gerenciá-lo com o logrotate, se necessário.

    
por 11.06.2015 / 20:31