linux服務器日誌分析,內入提取過濾再編輯[grep,sed,sort,awk]

概述html

linux環境下,平常應用中都離不開日誌。日誌是咱們在排查問題的一個重要依據。可是日誌並非寫了就行了,當你想查看日誌的時候,你會發現線上日誌堆積的長度已經超越了你一行行瀏覽的耐性的極限了。因而,頗有必要經過一些手段來高效地輔助你來快速的從日誌中找到你要找的問題。linux

最基礎的日誌查看命令

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

查找關鍵字:grep
瀏覽了日誌文件後你會發現,日誌文件成千上萬行,用grep來進行日誌的關鍵行提取正則表達式

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

e.g.spa

grep 'duweixin.net' duweixin.log #在文件duweixin.log中查找全部包行duweixin.net的行.net

e.g.
-o選項只提取 http://www.duweixin.net/weixi... 的內容(而不是一整行),並輸出到屏幕上命令行

grep -o 'http://duweixin.net/ [a−A]+' duweixin.log日誌

e.g.
輸出文件duweixin.log中查找全部包行ERROR的行的數量code

grep -c 'ERROR' duweixin.loghtm

e.g.
查找不含"ERROR"的行

grep -v 'ERROR' duweixin.log

精簡日誌內容:sed

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

sed簡單用法:

-n選項是默認不輸出信息,除非使用了p命令或者是s命令的p標誌符;-e是代表空格後面接的是一個命令

sed -n '命令' 文件

這個用法是把命令寫在腳本里

sed [-n] -f 腳本 文件

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

e.g.
輸出duweixin.log中的某個日期中的ERROR的行

sed -n '/^2016-06-21.*ERROR/p' duweixin.log

輸出結果:

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

提取duweixin.log中的日期,日誌級別,訂單id和狀態。

sed -f demo.sed2 demo.log

http://www.reddragonfly.org/a...

對記錄進行排序 sort

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

基本使用

sort [options] [file...]

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

排序功能
-t表示用@做爲分割符,
-k表示用分割出來的第幾個域排序

sed -f test.sed duweixin.log | sort -t@ -k2,2n -k3,3r -k1,1

n爲按數字排序,r爲倒序

統計日誌相關記錄數 awk

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

awk簡單使用:

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

打印日誌中的第2,3列
BEGIN中預處理的是,把@號做爲行的列分割符,把分割後的行的第2,3列輸出

awk 'BEGIN{FS="@"} {print $2,$3}' duweixin.log_after_sort

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

下面的例子是做爲命令行輸入的,利用單引號做爲換行標記,這樣就不用另外把腳本寫進文件調用了

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

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

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

sed -f duweixin.sed duweixinlog.log | sort -t@ -k2,2n -k3,3r -k1,1 | awk -f demo.awk
#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>

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

awk統計某個開始-結束範圍內的關鍵字累加總數:

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)  
}

示例

100.109.192.199 - - [29/Jun/2016:03:10:38 +0800] "POST /user/device HTTP/1.0" 200 226 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)" "114.111.167.93" "0.010" "0.010"
100.109.192.204 - - [29/Jun/2016:03:10:39 +0800] "POST /user/my_subscribe HTTP/1.0" 200 24494 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)" "114.111.167.93" "0.222" "0.222"
100.109.192.197 - - [29/Jun/2016:03:10:41 +0800] "POST /user/personal_user HTTP/1.0" 200 651 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)" "114.111.167.93" "0.018" "0.019"
100.109.192.200 - - [29/Jun/2016:03:10:48 +0800] "POST /user/creation_article HTTP/1.0" 200 97 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)" "114.111.167.93" "0.136" "0.136"
100.109.192.196 - - [29/Jun/2016:03:10:51 +0800] "POST /user/creation_article HTTP/1.0" 200 97 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)" "114.111.167.93" "0.135" "0.136"
100.109.192.202 - - [29/Jun/2016:03:10:53 +0800] "POST /article/delete HTTP/1.0" 200 24 "-" "BetweenTheLines/1.5.2 (iPhone; iOS 9.3.2; Scale/3.00)"

要求:

獲取請求接口和最後兩列,並按列排序

cat access.log | grep -F "POST" | awk '{print $18,$19,$7}' > result.txt  #彙總過濾數據
sort -k1 result.txt  #按第一列排序

獲取第一列

文檔

軍事@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
天氣@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
廣告@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
幽默搞笑@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
科學@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
星座@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
其餘@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997
未分類@其它#bd4a9e23-6c5d-480e-9baf-7cb0e9f9d997

awk -F "@" '{print $1}' classify_map

相關文章
相關標籤/搜索