[英]How to pipe tail -f into awk
我正在嘗試設置一個腳本,當某個字符串出現在日志文件中時會生成警報。
已經存在的解決方案每分鍾刷一次整個日志文件並計算字符串出現的頻率,使用日志行的時間戳僅計算前一分鍾中的出現次數。
我認為用尾巴做這個會更有效率,所以我嘗試了下面的測試:
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一起工作?
假設您的日志看起來像這樣:
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
(大寫tail -F
F),因為它處理日志老化。 每個操作系統都不支持此功能,但它應該適用於現代BSD和Linuces。
這是如何運作的?
awk腳本包含一組test { commands; }
test { commands; }
評價針對輸入的每一行。 (有兩個特殊的測試, BEGIN
和END
,它們的命令分別在awk啟動和awk結束時運行。在你的問題中,awk永遠不會結束,所以END
代碼從未運行過。)
上面的腳本有三個測試/命令部分:
NR == 1
是僅在第一行輸入上評估為真的測試。 它運行的命令為last
變量創建初始值,在下一節中使用。 /account failure reason/
,我們遞增計數器。 像泥一樣清楚? :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.