2012-07-13 49 views
5

我試圖設置一個腳本,當某個字符串出現在日誌文件中時會生成警報。如何將tail -f拖入awk

已經到位的解決方案裏grep整個日誌文件每分鐘一次,並計數串出現的頻率,使用日誌行的時間戳來算只有前一分鐘發生。

我想這將是更有效的帶尾巴要做到這一點,所以我嘗試了以下方面的測試:

FILENAME="/var/log/file.log" 

tail -f $FILENAME | awk -F , -v var="$HOSTNAME" ' 
       BEGIN { 
         failed_count=0; 
       } 
       /account failure reason/ { 
         failed_count++; 
       } 
       END { 
         printf("%saccount failure reason (Errors per Interval)=%d\n", var, failed_count); 
       } 
' 

但這只是掛不輸出任何東西。有人提出這個小小的變化:

FILENAME="/var/log/file.log" 

awk -F , -v var="$HOSTNAME" ' 
       BEGIN { 
         failed_count=0; 
       } 
       /account failure reason/ { 
         failed_count++; 
       } 
       END { 
         printf("%saccount failure reason (Errors per Interval)=%d\n", var, failed_count); 
       } 
' <(tail -f $FILENAME) 

但這樣做的事情。

我正在使用的awk(我在上面的代碼中已經簡化了)的工作原理,因爲它用於現有腳本中,其中grep「^ $ TIMESTAMP」的結果已被傳入。

我的問題是,怎樣才能得到尾-f使用awk工作?

+4

當你'tail -f'時,你的awk腳本永遠不會到達END。所以你不斷計算錯誤,但從不打印任何東西。您需要運行printf並重置計數器的另一個條件(例如,檢測到它是新的一天)。向我們展示您的日誌樣本,我們可以提出修正建議。 – ghoti 2012-07-13 11:57:32

回答

4

假設您的日誌看起來是這樣的:

Jul 13 06:43:18 foo account failure reason: unknown 
│ │  
│ └── $2 in awk 
└────── $1 in awk 

你可以做這樣的事情:

FILENAME="/var/log/file.log" 

tail -F $FILENAME | awk -v hostname="$HOSTNAME" ' 
    NR == 1 { 
     last=$1 " " $2; 
    } 
    $1 " " $2 != last { 
     printf("%s account failure reason (Errors on %s)=%d\n", hostname, last, failed); 
     last=$1 " " $2; 
     failed=0; 
    } 
    /account failure reason/ { 
     failed++; 
    } 
' 

請注意,我已經改變了這tail -F(大寫F),因爲它處理日誌老化。這在每個操作系統中都不被支持,但它應該在現代BSD和Linuces中運行。

這是如何工作的?

的awk腳本包括套test { commands; }對輸入的每一行評價。 (有兩個特殊的測試,BEGINEND其命令運行時AWK開始,當awk的兩端,分別在你的問題,AWK永不落幕,所以END代碼是永遠不會運行。)

上面的腳本有三個測試/命令部分:

  • 第一個,NR == 1是一個測試,僅在輸入的第一行評估爲真。它運行的命令創建了last變量的初始值,在下一節中使用。
  • 在第二部分中,我們測試自上一行評估以來「最後」變量是否發生了變化。如果這是真的,則表示我們正在評估新的一天的數據。現在是時候打印上個月的摘要(日誌),重置我們的變量並繼續前進。
  • 第三,如果我們正在評估的行匹配正則表達式/account failure reason/,我們會增加計數器。

清除泥? :-)

+0

+1 - 爲了做錯誤/日,你需要保持計數的日子,並進行分工。或者您可以將您的措辭更改爲「昨天的錯誤」並重置「failed_count」。 – 2012-07-13 12:38:18

+0

哦,現貨!不知道它在做什麼,但很好,謝謝! – mazz0 2012-07-13 13:29:53

+0

@DennisWilliamson - 對,謝謝你指出。我已經更新了答案,以便代碼提供更清晰的結果。 – ghoti 2012-07-13 20:04:01