為了分析hadoop的日志,特地寫了個一行的程式,來分析日志程式。Hadoop 是個分布式程式,程式分布在多個節點上,日志自然也是多份的,這裡用一行腳本提取所有日志中的關鍵内容,進行重新排序,友善跟蹤,主要是 sed 應用
grep "blk_" hadoop-testhdp-* | sed -ne ‘s/^hadoop-testhdp-\([a-z]\{8\}\)-[a-z]\+-\([0-9]\{1,2\}-[0-9]\{1,2\}\).local.log[^:]*:\(20[0-9]\{2\}-1\?[0-9]-[0-9]\{1,2\} [0-9:,]\{10,12\}\)\(.*\)\(blk_-\?[0-9]\{19\}_[0-9]\{4\}\)\(.*\)$/ \5 \3 [\1] c\2: \4 [The BLK] \6/p’| sort |while read blk remain;do [ "$blk" != "$last" ] && echo "—————-" ; last=$blk ; echo $blk $remain ;done > blocks_log_seg.txt
這個程式主要有兩個部分,while之前的是将所有日志放在一起,并提取每行的關鍵資訊,重新排列,然後排序,這樣就按照我們關心的方式來排列了,後面一部分(while)是将首個字段發生變化的位置标記出來,以友善檢視。sed裡面有這麼一些關鍵點:
指定某個表達式的長度:
\{8\} 8個長
\{10,12\} 10到12個長
\+ 至少一個長
\? 可能有一個
* 多少個都有可能,沒有也有可能
\( \) 括起來的内容在後面依次可以用 \1, \2, \3…. 的方式來引用
使用 [ ] 來指定可能的字元,或用 [^] 來排除沒有的,如 [^:] 就是不包含冒号的,上述[^:]* 如果替換成 .* 的話,可能在 log: 2008-11-28 13:05:33 中做最大比對,一直到33前面,紅色部分的比對可能是無門不希望看到的。
後面的 while 實際上儲存了上一行的 $blk,然後和目前行作比較,如果不同就加如一行減号,進而分隔開不同的行,如果沒有需要的話可以去掉,這樣會運作得更快些。
注意,該程式的 while 部分在 linux 中運作速度尚可,在 cygwin 中幾乎無法接受,如果用 cygwin 的話,建議要麼去掉這部分,要麼做好等很長時間的準備。