Restringir o tamanho do arquivo de log

1

Estou tentando limitar o número de linhas no meu arquivo de log usando:

php $PWD/private_html/run_worker.php | head -n 20000 >> $PWD/private_html/data/logfile.txt 2>&1 &

Se eu executar o comando sem o "| head -n 20000", minha saída será redirecionada. No entanto, quando incluo o código de limitação, nada é gravado no log.

Qualquer ajuda seria apreciada.

    
por Eric 17.11.2016 / 23:55

1 resposta

1

Sofrendo de Buffer

Primeiro, pode haver buffering; por padrão, a saída para não-terminal-não-padrão-erro é bufferizada por bloco (por setvbuf (3) ), portanto, não se deve esperar ver nenhum registro até que um buffer seja preenchido (ou não, quando algo quebra ou come um sinal fatal). Isso é melhor testado com dois terminais, um para executar os comandos e outro para tail -f do arquivo de saída:

# terminal watcher (how do the log lines appear in the logfile?)
rm logf; touch logf; tail -f logf

# terminal test commands (feed logfile)
php -r 'while(1){echo "logline\n";sleep(1);}' >> logf
...
^C
perl -E 'while(1){say "logline";sleep 1}' >> logf
...
^C

A partir disso, aparece (pelo menos no meu sistema) que o PHP não bloqueia o padrão do buffer, uma partida do padrão; no entanto, head faz buffer e stdbuf não ajuda, pois todas as linhas de log aparecem em um clump:

php -r 'while(1){echo "logline\n";sleep(1);}' | head -7 >> logf
php -r 'while(1){echo "logline\n";sleep(1);}' | stdbuf -o 0 -- head -7 >> logf

Portanto, head provavelmente não é a ferramenta certa para essa tarefa. (Como uma nota lateral, vários aplicativos armazenarão buffer internamente, portanto, quaisquer coisas horríveis que o stdbuf esteja fazendo podem não ajudar:

stdbuf -o 0 perl -E 'while(1){say "logline";sleep 1}' >> logf
perl -E 'STDOUT->autoflush;while(1){say "logline";sleep 1}' >> logf

Se for possível, defina o buffer apropriado no próprio aplicativo.

Quanto aos Logs

Um limite rígido em linhas de registro exigiria algo que consome N linhas, mas permaneça aberto (ou o aplicativo será morto ou ...?):

php -r 'while(1){echo "logline\n";sleep(1);}' 2>&1 \
| perl -ne 'BEGIN{STDOUT->autoflush; $N=7 } if($N>0){print;$N--}' >> logf

Ou isso pode ser feito internamente com PHP, assumindo que todos os logs podem ser roteados através de uma função para manipular essa tarefa, ou um módulo ou estrutura de registro. Caso contrário, existem várias ferramentas que registram a rotação padrão , com vários níveis de opções e curvas de aprendizado envolvidas, embora pareçam carecer de "N linhas" e, em vez disso, definir limites com base no tamanho.

    
por 18.11.2016 / 18:13