Io-Redirection

限制日誌文件大小

  • November 18, 2016

我正在嘗試使用以下方法限制日誌文件中的行數:

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

如果我在沒有“| head -n 20000”的情況下執行命令,我的輸出將被重定向。但是,當我包含限制程式碼時,不會將任何內容寫入日誌。

任何幫助,將不勝感激。

緩沖之苦

首先,可能有緩衝;預設情況下,非終端非標準錯誤的輸出是塊緩衝的(根據setvbuf(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 行”,而是根據大小設置上限。

引用自:https://unix.stackexchange.com/questions/324137