Como limitar um arquivo de log às últimas N linhas?

0

Eu tenho um ./program que gera muitas mensagens de registro e também possui espaço de armazenamento muito limitado no meu VPS:

I would like my log-file to contain only the latest N lines all the time (or rather when I terminate ^C my program or when it crashes...)

Eu faço não quero o seguinte:

  1. "Redirecione a saída para um arquivo (log) e use tail para manter apenas as últimas N linhas."

    Bem, o arquivo de log ainda levaria um precioso espaço até eu rodar tail nele, o que torna isso inútil ... Eu posso configurar um cronjob para fazê-lo periodicamente se eu não tiver outra escolha, mas eu gostaria de explorar as possibilidades primeiro.

  2. "Use logrotate . "

    logrotate parece ser a solução adequada para o problema, mas é muito trabalhoso e eu quero algo mais simples, de preferência algo que eu possa fazer com canos e redirecionamentos.

B. Eu tentei o seguinte:

(substituído ./program com seq 1000000 se para teste)

  1. seq 1000000 | tee /dev/fd/2 | tail -n 10 > logfile

    Funciona perfeitamente bem quando termina sozinho, mas quando eu interrompo ^ C eu mesmo, o logfile está vazio (enquanto eu espero que ele contenha as últimas 10 linhas que estão impressas no tela por tee )

  2. mkfifo fifo; tail fifo -n 10 > logfile & seq 1000000 | tee fifo

    Funciona perfeitamente bem quando termina sozinho, mas quando eu interrompo ^ C eu mesmo, o logfile é não vazio, mas também não contém um pouco das últimas entradas de log que são impressas na tela:

.

$ tail fifo -n 10 > logfile & seq 1000000 | tee fifo
[1] 2616
1
2
3
⋮
480178
480179
480180
480181
480182
480183
^C
[1]+  Done                    tail fifo -n 10 > logfile
$ cat logfile
479297
479298
479299
479300
479301
479302
479303
479304
479305

Aqui você pode ver que as últimas entradas estão em 480 mil, enquanto a última entrada no logfile é 479,305 ... o que significa que eu perdi 878 linhas mais recentes! Eu acho que isso tem algo a ver com o buffer, mas não tenho certeza.

Alguém pode me mostrar como fazer isso usando apenas shell e (preferencialmente padrão) utilitários Linux? Obrigado!

    
por Bora M. Alper 29.07.2018 / 19:07

1 resposta

0

A solução mais simples para o seu caso é provavelmente o log circular, que tem tamanho fixo.

Se você está no Linux, você pode tentar o módulo do kernel emlog

The emlog kernel module implements simple character device driver. The driver acts like a named pipe that has a finite, circular buffer. The size of the buffer is easily configurable. As more data is written into the buffer, the oldest data is discarded. A process that reads from an emlog device will first read the existing buffer, then see new text as it's written, similar to monitoring a log file using "tail -f". (Non-blocking reads are also supported, if a process needs to get the current contents of the log without blocking to wait for new data.)

Em sistemas BSD, consulte CLOG(8)

    
por 29.07.2018 / 20:48

Tags