Questão Como limitar um arquivo de log para as últimas N linhas?


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

Eu gostaria que meu arquivo de log contivesse apenas as últimas N linhas  o tempo todo (ou melhor, quando termino ^ C meu programa ou quando cai ...)

A. 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 precioso ter espaço até que eu corra tail sobre isso, o que torna inútil ... Eu posso definir um cronjob para fazê-lo periodicamente, se não tiver outra escolha, mas eu gostaria de explorar as possibilidades primeiro.

  2. "Usar logrotate"

    logrotate parece ser a solução adequada para o problema, mas é muito complicado 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á vazia (enquanto espero que contenha as últimas 10 linhas impressas na 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 ... ou seja, eu sinto falta das últimas 878 linhas! 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!


0


origem


Pessoalmente eu uso um cron que roda todos os dias às 12:12:12 para limpar os arquivos de log ... já que eles são redimensionados diariamente, eles nunca ficam grandes, o cron gera alguns html para um arquivo que é incluído em uma página de status pessoal (mistura de php e html) que me permite rapidamente ficar de olho nas coisas. - Tyson


Respostas:


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

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

O módulo do kernel emlog implementa um driver de dispositivo de caractere simples. O driver funciona como um pipe nomeado que possui um buffer circular finito. O tamanho do buffer é facilmente configurável. Quanto mais dados são gravados no buffer, os dados mais antigos são descartados. Um processo que lê a partir de um dispositivo de emlog primeiro lê o buffer existente e, em seguida, vê o novo texto como está escrito, semelhante ao monitoramento de um arquivo de log usando "tail -f". (Leituras sem bloqueio também são suportadas, se um processo precisar obter o conteúdo atual do log sem bloqueio para aguardar novos dados.)

Nos sistemas BSD, consulte CLOG(8)


0