清理 Apache 存取日誌檔案嗎?

清理 Apache 存取日誌檔案嗎?

我們在 shell 腳本中包含此程式碼,該腳本透過管道輸出供 Apache 記錄。

declare -a values=( $taintRequestVals )

for item in ${!values[@]}
do
    cat $apacheLog | sed "s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g" | /bin/grep ${values[$item]}=
done

然而,這是極其低效的。在幾秒鐘內,數量access.log呈指數級增長了四倍,直至伺服器的根切片被填滿。尋找更好的方法,在 Apache 寫入access.log.

答案1

這裡的問題是,您正在讀取 Apache 日誌並同時寫入。無論您新增至日誌中的是什麼,也會透過呼叫將其返回到管道中cat(沒有雙關語的意圖:))。這會創建一個令人討厭的正回饋循環,該循環將繼續工作,直到您的檔案系統填滿為止。答案是這個問題您可能對為什麼會發生這種情況感興趣。

那你該怎麼辦呢?一個簡單的解決方案是像這樣修改檔案:

for item in ${!values[@]};do
    sed -i "..." "$apacheLog"  #cat isn't needed here
done

並且不要將輸出傳送到任何地方:腳本本身將修改文件就地。另請參閱terdon的答案,了解如何sed僅調用一次(不循環)以提高效率。

然而,這種方法的問題在於,當您處理文件時,即時 Apache 伺服器可能會將內容記錄到文件中,並且可能會開始發生奇怪的事情。更好的解決方案是在 Apache 文件中尋找將敏感資訊排除在日誌之外的方法。

順便說一句,您正在做的事情甚至沒有清理日誌:它將清理後的行附加回(仍然受污染的)日誌檔案中。

答案2

就目前情況而言,您可以進行各種改進。首先,也是最不重要的,你有一個對貓的無用利用。更重要的是,您運行了sed多次,每次都會列印整個文件。我不太確定你在做什麼grep,你是否試圖只列印那些包含特定變數的行?

不管怎樣,一種做得更好的方法是運行sed一次並讓它完成所有替換。就像是:

replace=""
for item in ${!values[@]}
do
    ## build the sed line
    replace="s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g;$replace"
done

### run the replacement using sed's -i option so it 
### changes the original file
eval sed -i \""$replace"\" $apacheLog

相關內容