概述 html
咱們平常應用中都離不開日誌。能夠說日誌是咱們在排查問題的一個重要依據。可是日誌並非寫了就行了,當你想查看日誌的時候,你會發現線上日誌堆積的長度已經超越了你一行行瀏覽的耐性的極限了。因而,頗有必要經過一些手段來高效地輔助你來快速的從日誌中找到你要找的問題。本文經過一個從項目中衍生出來的例子從查找日誌,篩選日誌和統計日誌3個方面層層遞進來簡述日誌文件查看中一些有用的手段。(注:在linux環境下) java
目錄 linux
0.查找關鍵日誌grep 正則表達式
1.查找關鍵日誌grep shell
2.精簡日誌內容 sed bash
4.統計日誌相關記錄數 awk less
5.日誌規範化 ssh
6.一些容易遇到的問題 函數
例子背景:
後臺跑一個定時任務,對指定時間段的訂單數據表中的每一條記錄進行以此任務處理。在日誌中輸出:
1.訂單id
2.訂單處理狀態
3.日誌類別
準備工具:sort, tail, less, uniqu,grep,sed,awk
示例日誌:demo.log
0.一些最基礎的日誌查看命令
最簡單的日誌查看命令就是瀏覽日誌文件了,通常會從有限瀏覽文件末尾的
以上命令具體使用詳見本機man手冊
1.查找關鍵日誌記錄 grep
瀏覽了日誌文件後你會發現,日誌文件成千上萬行,怎麼能找到我要找的內容呢。這時候,就可已用grep來進行日誌的關鍵行提取了。
grep 簡單使用
規則:grep [選項]...模式 [文件]... (模式是正則表達式)
例子1:
輸出:
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:
例子3:
輸出:17
例子4:
grep 用法小結(轉自網絡圖片):請點擊直接查看大圖
詳細用法請man之
2.精簡日誌內容 sed
從n多行的日誌文件中提取到必定數量的行後,可能你還會以爲有些功能不夠,好比你每行並不須要有哪一個類拋出的描述,好比你不須要日誌時間,或者要把時間格式換個形式展現等等,這時候你就能夠經過sed的替換命令來進行對日誌文件提取具體內容了。
若是把grep比做過濾器,那sed就是個修改器了。
sed簡單用法:
»'命令'的格式: [地址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 | 全局 | 在每一個匹配的輸入行中, 將每一個模式匹配都做相應的操做. (譯者注: 不僅侷限於第一個匹配) |
例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的行
來具體應用下:
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和狀態。
輸出:
2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳過
sed詳細用法能夠參考《sed 與 awk》(第二版), 或者man之
或者點擊下面這個參考連接http://www.reddragonfly.org/abscn/x17814.html
3.對記錄進行排序 sort
通過了日誌文件的精煉後,咱們可能不想對日誌進行時間排序,這時候咱們就能夠用sort進行排序。
基本使用
sort [options] [file...]
對於demo.log,通過了上面的sed提取後,我但願先用id進行排序,而後再用日誌級別倒序進行排序,最後纔是日期排序
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簡單使用:
和sed同樣,awk也支持2中方式調用,一種是把awk腳本直接在命令行寫入,第二種是把awk寫在文件中在命令行中調用。
awk處理方式也與sed相似,對文件中的每個輸入行進行處理,每一個處理首先判斷是不是模式中匹配的行,是的話就具體執行相應的語句。
不一樣的是,awk側重與對每一行的列進行處理,而且,awk腳本和c語言相似也擁有變量,條件判斷,循環等複雜語句,因此這裏只能簡單介紹一下基本應用,詳細的請查看後面給出的相關連接。並且,awk在處理全部行前和處理完行後各有BEGIN和END語句作預處理和後置處理。
例子1:打印日誌中的第2,3列
例子2. 統計日誌中INFO,ERROR出現的總數,以及總記錄數
輸出:
order total count:22
INFO count:5 ERROR count:17
例子3. 對指定時間範圍內的日誌進行統計,包括輸出INFO,ERROR總數,記錄總數,每一個訂單記錄分類統計
下面的例子綜合了前面sed和sort
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》(第二版)
補充:
其餘實踐時例子:
1. 在本地分支把代碼修改從一個分支複製到另外一個分支(例子的b1022st.txt是一個記錄了文件新增或修改的變化的文件路徑名)
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統計某個開始-結束範圍內的關鍵字累加總數:
5.日誌規範化
從前面能夠看出,日誌文件爲了要讓後續工具可以對裏面的內容進行提取和處理,就必需要讓日誌文件規範的輸出。
我的想到有幾個點能夠規範:
1.記錄日誌時候能夠寫入一些特殊的文本語句,一遍與工具的檢索和處理。
2.記錄日誌最好不要用中文,由於在不一樣語言環境下對日誌的處理可能由於編碼不一樣致使無法處理日誌。
後面再貼下淘寶中找到的一些打印日誌的建議:
6.一些容易遇到的問題
a.處理中文出現亂碼
這個主要是由於你的linux locale的配置,與編輯文件的語言環境,還有你登陸ssh客戶端的編碼規則有關,因此最好仍是不用中文記錄日誌。
b.正則表達式不一樣工具的區別
這個主要是由於不一樣工具的正則表達式定義的元字符不一樣,網上有總結的,可點擊正則迷霧參考
OO後記:
目前只是簡單介紹了grep,sed,sort,awk的幾個簡單應用,實際上的日誌監控回根據不一樣的情景進行不一樣的處理。好比須要對調用的耗時進行統計(平均時間或者超時記錄),對訪問量進行統計,可是基本原理都和本文例子出發點一致。本文一方面是爲了記錄下學習過程當中積累的東西,另外一方面爲了拋磚引玉引發你們對日誌記錄的關注。