grep,sed,sort,awk運用

概述

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


目錄

0.查找關鍵日志grep

1.查找關鍵日志grep

2.精簡日志內容 sed

3.對記錄進行排序sort

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

5.日志規范化

6.一些容易遇到的問題

 

例子背景:

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

        1.訂單id

        2.訂單處理狀態

        3.日志類別

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

示例日志:demo.log

[plain] view plaincopy

    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跳過  
    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  
    2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids成功保存為0|100104|0|100105|100107  
    2011-08-23 19:57:32,782 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:attr_ids不含0跳過  
    2011-08-23 19:57:32,805 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104  
    2011-08-23 19:57:33,828 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107  
    2011-08-23 19:57:33,838 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46  
    2011-08-23 19:57:34,850 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106  
    2011-08-23 19:57:35,860 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105  
    2011-08-23 19:57:36,871 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
    2011-08-23 19:57:36,884 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10226,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
    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  
    2011-08-23 19:57:36,891 [] INFO  bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:attr_ids不含0跳過  
    2011-08-23 19:57:36,928 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  
    2011-08-23 19:57:36,942 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100104  
    2011-08-23 19:57:36,955 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100105  
    2011-08-23 19:57:36,969 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100107  
    2011-08-23 19:57:36,980 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:46  
    2011-08-23 19:57:36,992 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:100106  
    2011-08-23 19:57:37,011 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10222,status:添加屬性id,但由于沒有屬性在該分類下默認取匹配屬性名稱的第一個屬性id:3  


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

最簡單的日志查看命令就是瀏覽日志文件了,一般會從有限瀏覽文件末尾的

[plain] view plaincopy

    tail -400f demo.log #監控最后400行日志文件的變化 等價與 tail -n 400 -f (-f參數是實時)  
    less demo.log #查看日志文件,支持上下滾屏,查找功能  
    uniq -c demo.log  #標記該行重復的數量,不重復值為1  

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


1.查找關鍵日志記錄 grep

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

grep 簡單使用

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


例子1:

[plain] view plaincopy

    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 plaincopy

    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 plaincopy

    grep -c 'ERROR' demo.log   #輸出文件demo.log中查找所有包行ERROR的行的數量  

輸出:17

例子4:
[plain] view plaincopy

    grep -v 'ERROR' demo.log   #查找不含"ERROR"的行  

輸出:(功能和grep 'INFO' demo.log 命令一樣,輸出略)


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

詳細用法請man之

2.精簡日志內容 sed

        從n多行的日志文件中提取到一定數量的行后,可能你還會覺得有些功能不夠,比如你每行并不需要有哪個類拋出的描述,比如你不需要日志時間,或者要把時間格式換個形式展示等等,這時候你就可以通過sed的替換命令來進行對日志文件提取具體內容了。
        如果把grep比作過濾器,那sed就是個修改器了。 

sed簡單用法:

[plain] view plaincopy

    sed [-n][-e] '命令' 文件        #-n選項是默認不輸出信息,除非使用了p命令或者是s命令的p標志符;-e是表明空格后面接的是一個命令  
    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 plaincopy

    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 plaincopy

    sed -f demo.sed2 demo.log  

[plain] view plaincopy

    #n                                #這一行用法和命令中的-n一樣意思,就是默認不輸出  
    #demo.sed2  
      
    #下面的一行是替換指令,就是把19位長的日期和INFO/ERROR,id,和后面的一截提取出來,然后用@分割符把這4個字段重新按順序組合  
    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 plaincopy

    #排序功能 -t表示用@作為分割符,-k表示用分割出來的第幾個域排序(不要漏掉后面的,2/,3/,1,詳細意思看下面的參考鏈接,這里不做詳述)  
    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 plaincopy

    awk [-v 變量名=變量值] [-Fre] [--] '模式 { 語句 }' 變量名=變量值 文件名  
    awk [-v 變量名=變量值] [-Fre] -f 腳本文件 [--] 變量名=變量值 文件名  

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

awk處理方式也與sed類似,對文件中的每一個輸入行進行處理,每個處理首先判斷是否是模式中匹配的行,是的話就具體執行相應的語句。
不同的是,awk側重與對每一行的列進行處理,并且,awk腳本和c語言類似也擁有變量,條件判斷,循環等復雜語句,所以這里只能簡單介紹一下基本應用,詳細的請查看后面給出的相關鏈接。

而且,awk在處理所有行前和處理完行后各有BEGIN和END語句做預處理和后置處理。

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

[plain] view plaincopy

    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 plaincopy

    #下面的例子是作為命令行輸入的,利用單引號作為換行標記,這樣就不用另外把腳本寫進文件調用了  
    awk '  
    BEGIN {  
      FS="@"  
    }  
      
    {  
      if ($3 == "INFO") {info_count++}  
      if ($3 == "ERROR") {error_count++}  
      
    }  
      
    END {  
      print "order total count:"NR           #NR是awk內置變量,是遍歷的當前行號,到了END區域自然行號就等于總數了  
      printf("INFO count:%d ERROR count:%d\n",info_count,error_count)  
    } ' demo.log_after_sort  

輸出:

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

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

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

[plain] view plaincopy

    sed -f demo.sed demolog.log | sort -t@ -k2,2n -k3,3r -k1,1 | awk -f demo.awk  

[plain] view plaincopy

    #demo.awk  
    BEGIN {  
      FS="@"  
      stime="2011-08-23 19:57:31"  
      etime="2011-08-23 19:57:37"  
    }  
      
    $1 > stime && $1 < etime {  
      if ($3 == "INFO") {info_count++}  
      if ($3 == "ERROR") {error_count++}  
      
      ++total  
      
      status[$2]=status[$2]"\t"$1"\t"$3"\t"$4"\n"  
      
    }  
      
    END {  
      for(i in status){  
          printf("id:%s:\n%s\n",i,status[i])  
      }  
      
      print "order total count:"total  
      printf("INFO count:%d ERROR count:%d\n",info_count,error_count)  
    } <span style="font-size:18px;"><strong>  
    </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 plaincopy

    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 plaincopy

    BEGIN {  
      running=0  
      count=0  
      startRow="begin =====>" id            #id,nextId是通過-v 參數從外部傳入  
      endRow="begin =====>" nextId  
    }  
      
    $0 ~ startRow{    # ~是匹配運算符,判斷$0是否滿足startRow正則表達式  
      running = 1  
    #  printf("start\n")  
    }  
      
    $0 ~ endRow {  
      running = 0  
    #  printf("end\n")  
    }  
      
    {  
      if(running==1) {      # 僅在startRow 和 endRow 范圍內統計  
        if($0 ~ "it show") {  
    #        printf($0 "\n")  
            str=$0  
            sub(/^.*show times:/, "", str)  
            sub(/ .*$/, "", str)  
            printf(str "\n")  
            count = count + str  
        }  
      }  
    }  
      
    END {  
      printf("showTimeCount:"+count)  
    }  

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的幾個簡單應用,實際上的日志監控回根據不同的情景進行不同的處理。比如需要對調用的耗時進行統計(平均時間或者超時記錄),對訪問量進行統計,但是基本原理都和本文例子出發點一致。本文一方面是為了記錄下學習過程中積累的東西,另一方面為了拋磚引玉引起大家對日志記錄的關注。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容