最近在整理對於各個模塊的監控,須要有必定的實時性。好比,須要獲取最近幾分鐘內的日誌,而後看某些請求的數量以及響應時間是否符合要求。可是,線上服務的日誌,一般都是按照小時粒度進行切分
的,你不可能對一個文件進行直接的過濾操做。在此以前須要解決一個問題:在一份文件中,獲取最近一段時間的日誌。bash
固然,還有一個最最基礎的問題:你的日誌內容裏面是表示時間的字段的。(不打時間和請求ID的日誌簡直就是耍流氓!)函數
我一開始的想法是:估算平均請求壓力下,每5分鐘的日誌會有多少條,而後直接將cat
替換爲tail -n XXX
就能夠了。雖然修改起來很方便,可是是有明顯缺陷的:日誌
tail
出來的日誌的時間粒度是不同的。若是用來監控實時請求響應時間還算能接受,用來監控請求量就不行了;tail
出來的數字須要不斷調整。看來仍是要精確的獲取某個時間段的日誌才行。其實思路仍是比較清晰的:code
開始時間
和結束時間
兩個字段日誌時間
對於步驟1,使用date
命令就能夠獲取,這個簡單。ast
對於步驟2,通常日誌中的時間都會比較在日誌前面幾個字段,比較好提取,也不難。class
步驟4嘛,就看需求是什麼了,若是是獲取請求數目,直接用grep
和wc -l
就OK了。若是涉及到提取日誌字段,簡單的也能夠用cut
搞定,複雜就得用grep
或者awk
了。awk
最關鍵是步驟3如何實現,我想到的是在awk
中進行邏輯判斷,獲取日誌中的時間字段不難,可是若是時間字段是經過多個字段拼接而來的,好比2014-05-02
和17:25:00
,怎麼把他們放到一個變量裏面
呢?要是有像sprintf
這樣的函數就行了,沒想到,還真有!相似於下面這樣:監控
cat xxx.log | awk '{t=sprintf("%s %s", $2, $3);}'
還有一個問題,就是如何將BASH中的開始時間
和結束時間
變量傳入awk
呢?也有辦法的!awk
裏面有-v
選項,支持將外部變量傳入其中。那麼程序就相似於這樣了:基礎
start_time=`date -d"$last_minutes minutes ago" +"%Y-%m-%d %H:%M:%S"` end_time=`date +"%Y-%m-%d %H:%M:%S"` cat xxx.log | awk -v st="$start_time" -v et="$end_time" '{t=sprintf("%s %s", $2, $3); if(t>=st && t<=et){print $0}}'
最後,還有一個小問題,由於會按期切分日誌,因此須要考慮臨界時間點的狀況,把當前時間段和上個時間段的日誌同時做爲輸入便可。變量
這樣,精確獲取最近一段時間日誌的需求就獲得解決了。
--EOF--