Apache-2.2

如何編寫僅作用於新日誌條目的腳本

  • December 29, 2020

我覺得這應該是一件簡單的事情,但我很難弄清楚。

我正在嘗試編寫一個腳本來監視其中一個 apache 日誌文件並採取一些特定的操作。但是我應該如何監控日誌文件呢?

每次將新行寫入日誌時,我都希望檢查該條目以查看它是否與我要查找的內容匹配,以及是否發生 x。當我手動執行此操作時,我使用了 cat 或 tail -f。我不想通過 cron 每 30 秒執行一次腳本並瀏覽整個日誌(甚至最後 5 行),找出自上次腳本執行以來哪些行是新的,然後是一些事情。

有沒有辦法只檢查日誌中的單個新條目?

通過 cron 執行腳本但使用logtaillogtail2讀取文件將避免每分鐘讀取整個文件。Logtail 會跟踪它上次讀取的位置,並在您下次使用時跳轉到該點。

如果你想立即對新的日誌行採取行動,而不是在 cron 呼叫之間等待長達 59 秒,你將不得不使用tail -f或類似的東西。

Janne 和 Khaled 的答案都希望很好地解決這個問題。

您可以利用現有的 Linux 工具,如tailgrepnamed pipes. 首先,使用以下命令創建一個命名管道 (fifo):

$ mkfifo /tmp/myfifo

其次,創建一個將從該 fifo 文件中讀取的簡單腳本。這是一個簡單的例子:

#!/bin/bash
pipe=/tmp/myfifo

while true
do
   if read line <$pipe; then
       if [[ "$line" == 'quit' ]]; then
           break
       fi
       echo $line
   fi
done
echo "Reader exiting"

該腳本從命名管道中讀取並將該行列印到標準輸出,直到它獲得“退出”字樣。這只是一個可以定制的例子。

第三,用於tail讀取附加到 apache 日誌文件的新行並將輸出重定向到命名管道。

$ tail -n0 -F /var/log/apache2/access.log | grep some_text > /tmp/myfifo

-F選項意味著按名稱跟踪文件,這應該使其免受 logrotate 的影響。因此,它將始終遵循相同的文件名。-n0不獲取任何舊線路的方法。grep僅指示相關行很有用。

使用此解決方案,您不需要任何 cron 作業。只需執行上面顯示的腳本和 tail 命令。

引用自:https://serverfault.com/questions/355311