버퍼링을 겪다

버퍼링을 겪다

다음을 사용하여 로그 파일의 줄 수를 제한하려고 합니다.

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

"| head -n 20000" 없이 명령을 실행하면 출력이 리디렉션됩니다. 그러나 제한 코드를 포함하면 로그에 아무 것도 기록되지 않습니다.

어떤 도움이라도 대단히 감사하겠습니다.

답변1

버퍼링을 겪다

첫째, 기본적으로 버퍼링이 있을 수 있으며, 비종단 비표준 오류에 대한 출력은 블록 버퍼링됩니다(각각vbuf(3) 설정) 따라서 버퍼가 채워질 때까지(또는 무언가 충돌하거나 치명적인 신호를 먹는 경우 전혀 로그가 표시되지 않을 때까지) 로그를 볼 수 있을 것으로 기대해서는 안 됩니다. 테스트를 위해 두 개의 터미널을 사용하는 것이 가장 좋습니다. 하나는 명령을 실행하고 다른 하나는 tail -f파일을 출력하는 데 사용됩니다.

# 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

(적어도 내 시스템에서는) PHP는 기본값과 달리 표준 출력 버퍼링을 방지하지 않는 것으로 보이지만, head로그 stdbuf줄이 모두 한꺼번에 표시되기 때문에 도움이 되지 않습니다.

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

따라서 head아마도 작업에 적합한 도구가 아닐 수도 있습니다. (그런데 다양한 응용 프로그램이 내부적으로 버퍼링되므로 어떤 stdbuf끔찍한 일이 일어나더라도 도움이 되지 않을 것입니다.

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

가능하다면 애플리케이션 자체에서 적절한 버퍼링을 설정하십시오. )

로그의 경우

로그 줄에 대한 엄격한 제한을 적용하려면 N 줄을 사용해야 하지만 열린 채로 둡니다(그렇지 않으면 응용 프로그램이 종료됩니다...?).

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

또는 모든 로깅이 이 작업을 처리하기 위해 함수나 로깅 모듈 또는 프레임워크를 통해 라우팅될 수 있다고 가정하면 PHP를 사용하여 내부적으로 이 작업을 수행할 수 있습니다. 그렇지 않으면회전된 표준 출력을 로깅하기 위한 다양한 도구, 다양한 수준의 옵션 및 학습 곡선이 포함되어 있지만 "N 행"이 부족한 것처럼 보이고 대신 크기에 따라 제한됩니다.

관련 정보