grep,sed,sort,awk運用

概述 html

        咱們平常應用中都離不開日誌。能夠說日誌是咱們在排查問題的一個重要依據。可是日誌並非寫了就行了,當你想查看日誌的時候,你會發現線上日誌堆積的長度已經超越了你一行行瀏覽的耐性的極限了。因而,頗有必要經過一些手段來高效地輔助你來快速的從日誌中找到你要找的問題。本文經過一個從項目中衍生出來的例子從查找日誌,篩選日誌和統計日誌3個方面層層遞進來簡述日誌文件查看中一些有用的手段。(注:在linux環境下) java


目錄 linux

0.查找關鍵日誌grep 正則表達式

1.查找關鍵日誌grep shell

2.精簡日誌內容 sed bash

3.對記錄進行排序sort 網絡

4.統計日誌相關記錄數 awk less

5.日誌規範化 ssh

6.一些容易遇到的問題 函數

 

例子背景:

        後臺跑一個定時任務,對指定時間段的訂單數據表中的每一條記錄進行以此任務處理。在日誌中輸出:

        1.訂單id

        2.訂單處理狀態

        3.日誌類別

準備工具:sort, tail, less, uniqu,grep,sed,awk

示例日誌:demo.log

[plain]  view plain copy
  1. 2011-08-23 19:57:00,610 [] INFO  bo.CommodityCerOrderBO - =====>屬性訂正任務執行開始|每頁讀取100條數據  
  2. 2011-08-23 19:57:05,012 [] INFO  bo.CommodityCerOrderBO - 當前正在處理頁數:1  
  3. 2011-08-23 19:57:30,688 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳過  
  4. 2011-08-23 19:57:30,709 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100104  
  5. 2011-08-23 19:57:31,721 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100105  
  6. 2011-08-23 19:57:32,727 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100107  
  7. 2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids成功保存爲0|100104|0|100105|100107  
  8. 2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:attr_ids不含0跳過  
  9. 2011-08-23 19:57:32,805 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104  
  10. 2011-08-23 19:57:33,828 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107  
  11. 2011-08-23 19:57:33,838 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46  
  12. 2011-08-23 19:57:34,850 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106  
  13. 2011-08-23 19:57:35,860 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105  
  14. 2011-08-23 19:57:36,871 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
  15. 2011-08-23 19:57:36,884 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
  16. 2011-08-23 19:57:36,891 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:attr_ids成功保存爲6|100104|0|0|100107|46|100106|100105|3|3  
  17. 2011-08-23 19:57:36,891 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:attr_ids不含0跳過  
  18. 2011-08-23 19:57:36,928 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
  19. 2011-08-23 19:57:36,942 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104  
  20. 2011-08-23 19:57:36,955 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105  
  21. 2011-08-23 19:57:36,969 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107  
  22. 2011-08-23 19:57:36,980 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46  
  23. 2011-08-23 19:57:36,992 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106  
  24. 2011-08-23 19:57:37,011 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  


0.一些最基礎的日誌查看命令

最簡單的日誌查看命令就是瀏覽日誌文件了,通常會從有限瀏覽文件末尾的

[plain]  view plain copy
  1. tail -400f demo.log #監控最後400行日誌文件的變化 等價與 tail -n 400 -f (-f參數是實時)  
  2. less demo.log #查看日誌文件,支持上下滾屏,查找功能  
  3. uniq -c demo.log  #標記該行重複的數量,不重複值爲1  

以上命令具體使用詳見本機man手冊


1.查找關鍵日誌記錄 grep

瀏覽了日誌文件後你會發現,日誌文件成千上萬行,怎麼能找到我要找的內容呢。這時候,就可已用grep來進行日誌的關鍵行提取了。

grep 簡單使用

規則:grep [選項]...模式 [文件]...    (模式是正則表達式)


例子1:

[plain]  view plain copy
  1. grep 'INFO' demo.log     #在文件demo.log中查找全部包行INFO的行  

輸出:
2011-08-23 19:57:00,610 [] INFO  bo.CommodityCerOrderBO - =====>屬性訂正任務執行開始|每頁讀取100條數據
2011-08-23 19:57:05,012 [] INFO  bo.CommodityCerOrderBO - 當前正在處理頁數:1
2011-08-23 19:57:30,688 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳過
...(略)


例子2:

[plain]  view plain copy
  1. grep -o 'order-fix.curr_id:\([0-9]\+\)' demo.log    #-o選項只提取order-fix.curr_id:xxx的內容(而不是一整行),並輸出到屏幕上  
輸出:
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10117
order-fix.curr_id:10226
...(略)

例子3:

[plain]  view plain copy
  1. grep -c 'ERROR' demo.log   #輸出文件demo.log中查找全部包行ERROR的行的數量  

輸出:17

例子4:

[plain]  view plain copy
  1. grep -v 'ERROR' demo.log   #查找不含"ERROR"的行  
輸出:(功能和grep 'INFO' demo.log 命令同樣,輸出略)


grep 用法小結(轉自網絡圖片):請點擊直接查看大圖

詳細用法請man之


2.精簡日誌內容 sed

        從n多行的日誌文件中提取到必定數量的行後,可能你還會以爲有些功能不夠,好比你每行並不須要有哪一個類拋出的描述,好比你不須要日誌時間,或者要把時間格式換個形式展現等等,這時候你就能夠經過sed的替換命令來進行對日誌文件提取具體內容了。
        若是把grep比做過濾器,那sed就是個修改器了。 

sed簡單用法

[plain]  view plain copy
  1. sed [-n][-e] '命令' 文件        #-n選項是默認不輸出信息,除非使用了p命令或者是s命令的p標誌符;-e是代表空格後面接的是一個命令  
  2. sed [-n] -f 腳本 文件           #這個用法是把命令寫在腳本里  

»'命令'的格式: [地址1[,地址2]][!] 指令 [參數]
                       » 地址的格式:用行號標識(1 代表匹配第一行),或者用正則表達式匹配('^INFO'代表該地址匹配以INFO打頭的行)   
                       » 指令的例子:p打印指令,s替換指令,d刪除指令等等(如下表格摘自abs的sed小冊子):

操做符 名字 效果
[地址範圍]/p 打印 打印[指定的地址範圍]
[地址範圍]/d 刪除 刪除[指定的地址範圍]
s/pattern1/pattern2/ 替換 將指定行中, 將第一個匹配到的pattern1, 替換爲pattern2.
[地址範圍]/s/pattern1/pattern2/ 替換 地址範圍指定的每一行中, 將第一個匹配到的pattern1, 替換爲pattern2.
[地址範圍]/y/pattern1/pattern2/ transform 地址範圍指定的每一行中, 將pattern1中的每一個匹配到pattern2的字符都使用pattern2的相應字符做替換. (等價於tr命令)
g 全局 在每一個匹配的輸入行中, 將每一個模式匹配都做相應的操做. (譯者注: 不僅侷限於第一個匹配)
小結:sed就是遍歷對於輸入文件的每一行,若是該行匹配地址1,地址2的範圍以內,那麼就對這一行執行命令。

例1:(摘自abs的sed小冊子)

8d 刪除輸入的第8行.
/^$/d 刪除全部空行.
1,/^$/d 從輸入的開頭一直刪除到第1個空行(第一個空行也刪除掉).
/Jones/p 只打印那些包含"Jones"的行(使用-n選項).
s/Windows/Linux/ 在每一個輸入行中, 將第一個出現的"Windows"實例替換爲"Linux".
s/BSOD/stability/g 在每一個輸入行中, 將全部"BSOD"都替換爲"stability".
s/ *$// 刪除掉每行結尾的全部空格.
s/00*/0/g 將全部連續出現的0都壓縮成單個的0.
/GUI/d 刪除掉全部包含"GUI"的行.
s/GUI//g 將全部"GUI"都刪除掉, 並保持剩餘部分的完整性.

看完基本用法,讓咱們結合demo.log來具體應用下:

例2:輸出demo.log中的某個日期中的ERROR的行

來具體應用下:

[plain]  view plain copy
  1. sed -n '/^2011-08-23.*ERROR/p' demolog.log  
輸出:

2011-08-23 19:57:30,709 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:31,721 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100105
2011-08-23 19:57:32,727 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100107

例3:提取demo.log中的日期,日誌級別,訂單id和狀態。

[plain]  view plain copy
  1. sed -f demo.sed2 demo.log  
[plain]  view plain copy
  1. #n                                #這一行用法和命令中的-n同樣意思,就是默認不輸出  
  2. #demo.sed2  
  3.   
  4. #下面的一行是替換指令,就是把19位長的日期和INFO/ERROR,id,和後面的一截提取出來,而後用@分割符把這4個字段從新按順序組合  
  5. s/^\([-\: 0-9]\{19\}\).*\(INFO\|ERROR\) .*order-fix.curr_id:\([0-9]\+\),\(.*$\)/\1@\3@\2@\4/p   

輸出:

2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳過
2011-08-23 19:57:30@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:31@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100105
2011-08-23 19:57:32@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100107
2011-08-23 19:57:32@10117@INFO@status:attr_ids成功保存爲0|100104|0|100105|100107
...略


sed詳細用法能夠參考《sed 與 awk》(第二版), 或者man之

或者點擊下面這個參考連接http://www.reddragonfly.org/abscn/x17814.html


3.對記錄進行排序 sort

        通過了日誌文件的精煉後,咱們可能不想對日誌進行時間排序,這時候咱們就能夠用sort進行排序。

基本使用

sort [options] [file...]

對於demo.log,通過了上面的sed提取後,我但願先用id進行排序,而後再用日誌級別倒序進行排序,最後纔是日期排序

[plain]  view plain copy
  1. #排序功能 -t表示用@做爲分割符,-k表示用分割出來的第幾個域排序(不要漏掉後面的,2/,3/,1,詳細意思看下面的參考連接,這裏不作詳述)  
  2. sed -f test.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1                  #n爲按數字排序,r爲倒序  
輸出:

2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳過
2011-08-23 19:57:32@10117@INFO@status:attr_ids成功保存爲0|100104|0|100105|100107
2011-08-23 19:57:30@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:31@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100105
2011-08-23 19:57:32@10117@ERROR@status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100107
2011-08-23 19:57:36@10222@INFO@status:attr_ids不含0跳過
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3
2011-08-23 19:57:36@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46
2011-08-23 19:57:37@10222@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3
2011-08-23 19:57:32@10226@INFO@status:attr_ids不含0跳過
2011-08-23 19:57:36@10226@INFO@status:attr_ids成功保存爲6|100104|0|0|100107|46|100106|100105|3|3
2011-08-23 19:57:32@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:33@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107
2011-08-23 19:57:33@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46
2011-08-23 19:57:34@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106
2011-08-23 19:57:35@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105
2011-08-23 19:57:36@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3
2011-08-23 19:57:36@10226@ERROR@status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3

詳盡手冊http://ss64.com/bash/sort.html


4.統計日誌相關記錄數 awk

如今日誌已經比較清晰了,可是若是我想對不一樣日誌進行統計怎麼辦,好比我要統計全部ERROR的日誌記錄書,或者要統計每一個訂單有多少個ERROR?這就須要咱們的awk幫忙了。

awk簡單使用:

[plain]  view plain copy
  1. awk [-v 變量名=變量值] [-Fre] [--] '模式 { 語句 }' 變量名=變量值 文件名  
  2. awk [-v 變量名=變量值] [-Fre] -f 腳本文件 [--] 變量名=變量值 文件名  

和sed同樣,awk也支持2中方式調用,一種是把awk腳本直接在命令行寫入,第二種是把awk寫在文件中在命令行中調用。

awk處理方式也與sed相似,對文件中的每個輸入行進行處理,每一個處理首先判斷是不是模式中匹配的行,是的話就具體執行相應的語句。

不一樣的是,awk側重與對每一行的列進行處理,而且,awk腳本和c語言相似也擁有變量,條件判斷,循環等複雜語句,因此這裏只能簡單介紹一下基本應用,詳細的請查看後面給出的相關連接。

並且,awk在處理全部行前和處理完行後各有BEGIN和END語句作預處理和後置處理。

例子1:打印日誌中的第2,3列

[plain]  view plain copy
  1. awk 'BEGIN{FS="@"} {print $2,$3}' demo.log_after_sort   #BEGIN中預處理的是,把@號做爲行的列分割符,把分割後的行的第2,3列輸出  
輸出:(對於從sort得出的結果做爲輸入)
10117 INFO
10117 INFO
10117 ERROR
10117 ERROR
10117 ERROR
10222 INFO
...略

例子2. 統計日誌中INFO,ERROR出現的總數,以及總記錄數

[plain]  view plain copy
  1. #下面的例子是做爲命令行輸入的,利用單引號做爲換行標記,這樣就不用另外把腳本寫進文件調用了  
  2. awk '  
  3. BEGIN {  
  4.   FS="@"  
  5. }  
  6.   
  7. {  
  8.   if ($3 == "INFO") {info_count++}  
  9.   if ($3 == "ERROR") {error_count++}  
  10.   
  11. }  
  12.   
  13. END {  
  14.   print "order total count:"NR           #NR是awk內置變量,是遍歷的當前行號,到了END區域天然行號就等於總數了  
  15.   printf("INFO count:%d ERROR count:%d\n",info_count,error_count)  
  16. } ' demo.log_after_sort  

輸出:

order total count:22
INFO count:5 ERROR count:17

例子3. 對指定時間範圍內的日誌進行統計,包括輸出INFO,ERROR總數,記錄總數,每一個訂單記錄分類統計

下面的例子綜合了前面sed和sort

[plain]  view plain copy
  1. sed -f demo.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1 | awk -f demo.awk  
[plain]  view plain copy
  1. #demo.awk  
  2. BEGIN {  
  3.   FS="@"  
  4.   stime="2011-08-23 19:57:31"  
  5.   etime="2011-08-23 19:57:37"  
  6. }  
  7.   
  8. $1 > stime && $1 < etime {  
  9.   if ($3 == "INFO") {info_count++}  
  10.   if ($3 == "ERROR") {error_count++}  
  11.   
  12.   ++total  
  13.   
  14.   status[$2]=status[$2]"\t"$1"\t"$3"\t"$4"\n"  
  15.   
  16. }  
  17.   
  18. END {  
  19.   for(i in status){  
  20.       printf("id:%s:\n%s\n",i,status[i])  
  21.   }  
  22.   
  23.   print "order total count:"total  
  24.   printf("INFO count:%d ERROR count:%d\n",info_count,error_count)  
  25. } <span style="font-size:18px;"><strong>  
  26. </strong></span>  
輸出:

id:10117:

2011-08-23 19:57:32 INFO  status:attr_ids成功保存爲0|100104|0|100105|100107
2011-08-23 19:57:32 ERROR  status:添加屬性id,但因爲認證分類參數有誤默認取匹配屬性名稱的第一個屬性id:100107

id:10226:

2011-08-23 19:57:32 INFO  status:attr_ids不含0跳過
2011-08-23 19:57:32 ERROR  status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104
2011-08-23 19:57:33 ERROR  status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107
2011-08-23 19:57:33 ERROR  status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46
2011-08-23 19:57:34 ERROR  status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106
2011-08-23 19:57:35 ERROR  status:添加屬性id,但因爲沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105


#這個例子只是舉例說明awk的統計用法,實際運用中可能會統計超時的次數,頁面訪問次數等。


awk相關資料:

《sed 與 awk》(第二版)

  awk腦圖


補充:

其餘實踐時例子:

1. 在本地分支把代碼修改從一個分支複製到另外一個分支(例子的b1022st.txt是一個記錄了文件新增或修改的變化的文件路徑名

[plain]  view plain copy
  1. awk 'BEGIN{FS="b1022-scm/"} {system("cp -rf b1022-scm/"$2" b1022-lpscm/"$2);}' /home/nizen/b1022st.txt  
經過awk和其system命令結合,這樣就把文件從b1022-scm複製到b1022-lpscm下


2.內置函數 http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html
3.內建變量 http://www.linuxsong.org/2010/09/awk-built-in-variable/
4.shell變量傳遞 http://www.51testing.com/?uid-225738-action-viewspace-itemid-246383
5.awk統計某個開始-結束範圍內的關鍵字累加總數:

[java]  view plain copy
  1. BEGIN {  
  2.   running=0  
  3.   count=0  
  4.   startRow="begin =====>" id            #id,nextId是經過-v 參數從外部傳入  
  5.   endRow="begin =====>" nextId  
  6. }  
  7.   
  8. $0 ~ startRow{    # ~是匹配運算符,判斷$0是否知足startRow正則表達式  
  9.   running = 1  
  10. #  printf("start\n")  
  11. }  
  12.   
  13. $0 ~ endRow {  
  14.   running = 0  
  15. #  printf("end\n")  
  16. }  
  17.   
  18. {  
  19.   if(running==1) {      # 僅在startRow 和 endRow 範圍內統計  
  20.     if($0 ~ "it show") {  
  21. #        printf($0 "\n")  
  22.         str=$0  
  23.         sub(/^.*show times:/, "", str)  
  24.         sub(/ .*$/, "", str)  
  25.         printf(str "\n")  
  26.         count = count + str  
  27.     }  
  28.   }  
  29. }  
  30.   
  31. END {  
  32.   printf("showTimeCount:"+count)  
  33. }  
6. printf "10ms occur:%.2lf%%\n",t10/total*100 #輸出百分比數據,精確到百分位後2位


5.日誌規範化

從前面能夠看出,日誌文件爲了要讓後續工具可以對裏面的內容進行提取和處理,就必需要讓日誌文件規範的輸出。

我的想到有幾個點能夠規範:

1.記錄日誌時候能夠寫入一些特殊的文本語句,一遍與工具的檢索和處理。

2.記錄日誌最好不要用中文,由於在不一樣語言環境下對日誌的處理可能由於編碼不一樣致使無法處理日誌。

後面再貼下淘寶中找到的一些打印日誌的建議:

  • 正常狀況下應該返回true, 卻返回false的, 反正就是你在對返回值進行檢查的時候, 若是不正常, log一下
  • 出現異常的地方, 之前認爲hsf.log會幫咱們記下全部的異常, 可是這個也不必定可靠, 因此還得咱們本身記一下
  • 日誌必須包含上下文信息
  • 若是出於統計的須要, 可打可不打
  • 在完成代碼以後, 查看一下整個代碼結構, 在一些關鍵的點, 加上日誌, 正常的info, 少數狀況出現的warning, 異常狀況的error或者warning
  • 打印的日誌內容要容易查詢, 之前我比較傾向於打中文日誌, 雖然易讀, 可是中文在linux下的搜索統計稍微有些麻煩,因此若是能加上英文標識(好比說用於惟一標識的前綴), 能識別不一樣日誌, 這個對定位也是很是有好處的.

6.一些容易遇到的問題

a.處理中文出現亂碼

這個主要是由於你的linux locale的配置,與編輯文件的語言環境,還有你登陸ssh客戶端的編碼規則有關,因此最好仍是不用中文記錄日誌。

b.正則表達式不一樣工具的區別

這個主要是由於不一樣工具的正則表達式定義的元字符不一樣,網上有總結的,可點擊正則迷霧參考

OO後記:

目前只是簡單介紹了grep,sed,sort,awk的幾個簡單應用,實際上的日誌監控回根據不一樣的情景進行不一樣的處理。好比須要對調用的耗時進行統計(平均時間或者超時記錄),對訪問量進行統計,可是基本原理都和本文例子出發點一致。本文一方面是爲了記錄下學習過程當中積累的東西,另外一方面爲了拋磚引玉引發你們對日誌記錄的關注。

相關文章
相關標籤/搜索