Rotação de log do stdout?

43

Eu tenho um programa Linux que pode gravar informações para stdout e stderr.

Eu tenho um script de shell que redireciona essa saída para um arquivo em /var/log . (Via >> e 2>&1 .)

Existe uma maneira de fazer esse arquivo de log girar? (tamanho máximo, depois mude para um arquivo diferente, mantenha apenas um número limitado de arquivos)

Eu vi algumas respostas que falam sobre o programa logrotate , que soa bem, mas elas também parecem estar focadas em programas que estão gerando arquivos de log internamente e lidam com sinais HUP. Existe uma maneira de fazer isso funcionar com um script básico de redirecionamento de saída?

    
por Miral 01.06.2011 / 06:58

9 respostas

33

Como alternativa, você poderia canalizar a saída por meio de ferramentas projetadas com o objetivo principal de manter conjuntos de arquivos de log com limite de tamanho e rotação automática, como:

As ferramentas para processar os conjuntos de arquivos de log multilog -format incluem, entre outros:

Leitura adicional

  • Jonathan de Boyne Pollard (2015). " Registro ". A família dos daemontools . Respostas frequentemente dadas.
  • Jonathan de Boyne Pollard (2016). Não use logrotate ou newsyslog neste século. . Respostas frequentemente dadas.
  • link
por 01.06.2011 / 09:02
15

a ferramenta rotatelogs fornecida com o apache (no bin dir) (consulte docs ) recebe entrada de stdin e rotaciona o log após uma quantidade específica de tempo

    
por 01.06.2011 / 08:40
14

Se você puder ir para um dos fluxos de logs padrão (syslog, daemon, cron, usuário, segurança, correio, etc.), você pode usar o logger comando e canalizar para ele.

echo "Hello." | logger -p daemon.info

Caso contrário, talvez seja melhor você canalizar seu conteúdo registrado para um programa ou script personalizado para lidar com ele ou para configurar o logrotate configuração.

EDIT: resposta do JdeBP parece ter o que você pode estar procurando.

    
por 01.06.2011 / 09:20
13

Eu tive problema semelhante e inicialmente descartar logrotate mas acabou logrotate pode realmente fazer isso bem, a diretiva chave é " copytruncate ". Por alguma razão esse termo não surgiu em nenhum dos googling que eu fiz, então estou adicionando esta resposta para esclarecer exatamente como usá-lo para este caso.

O truque é que isso só funciona se o redirecionamento for feito com " > > " (anexar) em vez de " > "(criar).

Arquivo de configuração (truncate.cfg):

/tmp/temp.log {
    size 10M
    copytruncate
    rotate 4
    maxage 100
}

Programa de teste (nunca desiste de arquivo). Você pode assisti-lo preenchendo o disco e, embora a exclusão do logfile pareça funcionar, ele não liberará espaço no disco:

cat /dev/urandom >> /tmp/temp.log

Rodar o log de rotação:

logrotate truncate.cfg
    
por 24.10.2014 / 01:37
3

So is there a way to make logrotate work with an ongoing process's redirected stdout?

Sim! Confira a diretiva "copytruncate" oferecida pelo logrotate. Especificar que instrui o logrotate a lidar com esta situação: um programa simples que mantém seu arquivo de log aberto indefinidamente.

Uma advertência pode ou não ser um problema em sua situação:

Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost.

Curiosamente, vi algumas fontes de log do "mundo real" que incentivam os usuários a aplicar essa diretiva. Há alguma discussão sobre essa opção aqui .

    
por 15.10.2013 / 01:16
3

Use split, faz parte dos coreutils. Pode demorar stdin e dividi-lo em pedaços (com base no tamanho do pedaço ou número de linhas, etc.).

Exemplo:

app | split --bytes 1G - /var/logs/put-prefix-here

Note que dash (-) instrui "split" para usar stdin ao invés de arquivo.

    
por 11.06.2015 / 20:28
2

Eu gosto de multilog para meu caso de uso, mas meu caso de uso é tão trivial / simples que não é apresentado de maneira muito simples nos documentos / exemplos que encontrei. Aqui está um exemplo simples de rotação de vários passos:

mkdir /tmp/myapp
./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1

Algumas notas:

  • esse despejo registra no diretório / tmp / myapp /
  • o s10000 representa 10.000 bytes *
  • o n5 representa 5 arquivos. * O registro 'atual' conta como um dos arquivos, portanto inclui 4 registros mais antigos + 'atual'
  • é baseado em, adaptado dos exemplos fornecidos por François Beausoleil em: link
  • Eu não entendo muitas das opções - eu o encaminho para várias documentações para estender isso ...
  • Os documentos avisam que: "Note that running processor may block any program feeding input to multilog." em que 'processador' é a parte '!tai64nlocal' do comando

* Para muitas aplicações, estas são más escolhas para uso a longo prazo. Eles permitem que você observe o comportamento de encher e girar os logs mais rapidamente do que os logs grandes.

Finalmente, não se esqueça de nohup se necessário! Com nohup, você não precisa do 2>&1 (s = 10e6 e n = 30 aqui):

mkdir -p /tmp/myapp
nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp &

Esse comando deve começar.

    
por 28.10.2015 / 17:19
1

Eu só queria adicionar ao comentário de Sam Hendley acima:

O truque é que isso só funcionará se o redirecionamento for feito com >> (anexar) em vez de > (criar).

Eu encontrei o mesmo problema onde o arquivo original continua crescendo se você usa > (create) mas se você usa >> (append) o copyrtrate do Logrotate funciona lindamente e como esperado. O arquivo original volta para zero bytes e o programa continua a ser escrito.

Redirecionar STDOUT e STDERR para um arquivo de log rotativo:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. Crie um arquivo de configuração logrotate em /etc/logrotate.d chamado whatever, output_roll no meu caso.

    Exemplo de configuração para o meu caso:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. Configure seu cron job dentro do arquivo /etc/crontab

    *  *  *  *  * root /usr/sbin/logrotate /etc/logrotate.d/output_roll
    

    Isto irá verificar o arquivo a cada minuto. Você pode ajustar para atender às suas necessidades.

  4. Inicie:

    $> service crond restart
    
  5. É isso

Observação: Eu também tive um problema com o SELinux sendo definido como SELINUX=enforcing , então configurei para SELINUX=disabled .

    
por 03.04.2016 / 20:06
1

Eu escrevi um logrotee neste final de semana. Eu provavelmente não faria se eu tivesse lido a grande resposta do @JdeBP e multilog .

Eu me concentrei em ser leve e ser capaz de bzip2 seus pedaços de saída como:

verbosecommand | logrotee \
  --compress "bzip2 {}" --compress-suffix .bz2 \
  /var/log/verbosecommand.log

Ainda há muito a ser feito e testado.

    
por 10.07.2017 / 04:52