日志分析查看——grep,sed,sort,awk運用


 

引用地址: http://blog.csdn.net/ultrani/article/details/6750434 

 

概述

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

目錄

0.查找關鍵日志grep

1.查找關鍵日志grep

2.精簡日志內容 sed

3.對記錄進行排序sort

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

5.日志規范化

6.一些容易遇到的問題

7.Linux sed查看某時間段的系統日志

8.實例

 

Linux查找文件內容的常用命令方法

從文件內容查找匹配指定字符串的行: $ grep "被查找的字符串" 文件名

從文件內容查找與正則表達式匹配的行: $ grep –e “正則表達式” 文件名

查找時不區分大小寫: $ grep –i "被查找的字符串" 文件名

查找匹配的行數: $ grep -c "被查找的字符串" 文件名

從文件內容查找不匹配指定字符串的行:  $ grep –v "被查找的字符串" 文件名

從根目錄開始查找所有擴展名為.log的文本文件,並找出包含”ERROR”的行 find / -type f -name "*.log" | xargs grep "ERROR"

如果需要查找的內容包含特殊符號,比如$等等,grep要加參數 find ./ -name "*.php" | xargs grep -F '要查找的內容'

 

  

例子背景:

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

        1.訂單id

        2.訂單處理狀態

        3.日志類別

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

示例日志:demo.log 

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.一些最基礎的日志查看命令

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

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

1.查找關鍵日志記錄 grep

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

grep 簡單使用

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

例子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:

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:

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

輸出:17

例子4:

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

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

 

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

 

2.精簡日志內容 sed

 

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

 

sed簡單用法

   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的行

來具體應用下:

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和狀態。

sed -f demo.sed2 demo.log 
#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進行排序,然后再用日志級別倒序進行排序,最后才是日期排序

#排序功能 -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

 

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

 

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

現在日志已經比較清晰了,但是如果我想對不同日志進行統計怎么辦,比如我要統計所有ERROR的日志記錄書,或者要統計每個訂單有多少個ERROR?這就需要我們的awk幫忙了。

awk簡單使用:

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

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

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

不同的是,awk側重與對每一行的列進行處理,並且,awk腳本和c語言類似也擁有變量,條件判斷,循環等復雜語句,所以這里只能簡單介紹一下基本應用,詳細的請查看后面給出的相關鏈接。

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

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

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出現的總數,以及總記錄數

#下面的例子是作為命令行輸入的,利用單引號作為換行標記,這樣就不用另外把腳本寫進文件調用了
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

sed -f demo.sed demolog.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>

輸出:

 

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跳過

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

 

awk相關資料:

《sed 與 awk》(第二版)

  awk腦圖

 

補充:

其他實踐時例子:

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

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統計某個開始-結束范圍內的關鍵字累加總數:

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的幾個簡單應用,實際上的日志監控回根據不同的情景進行不同的處理。比如需要對調用的耗時進行統計(平均時間或者超時記錄),對訪問量進行統計,但是基本原理都和本文例子出發點一致。本文一方面是為了記錄下學習過程中積累的東西,另一方面為了拋磚引玉引起大家對日志記錄的關注。

 


 

Linux sed查看某時間段的系統日志

 

在系統應用集中部署的時候,很多日志因為太多難以定位,獲取某段時間的日志是對運維人員非常關鍵的事情。

 

一、sed查看某時間段到現在的系統日志:

sed  -n  '/May 20 17/,$p'   /var/log/messages  |  less 

 

二、sed 截選時間段日志

首先看一下日志的格式:

2010-11-17 09:25:55,606 [catalina-exec-74] INFO org.springframework.jdbc.datasource.JdbcTransactionObjectSupport  - JDBC 3.0 Savepoint class is available
2010-11-17 09:25:55,658 [catalina-exec-74] WARN org.hibernate.util.JDBCExceptionReporter  - SQL Error: 0, SQLState: null
2010-11-17 09:25:55,606 [catalina-exec-74] INFO org.springframework.jdbc.datasource.JdbcTransactionObjectSupport  - JDBC 3.0 Savepoint class is available2010-11-17 09:25:55,658 [catalina-exec-74] WARN org.hibernate.util.JDBCExceptionReporter  - SQL Error: 0, SQLState: null
……
ession for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.springframework.util.ReflectionUtils.handleReflectionException(ReflectionUtils.java:58)
at com.lottery.common.action.CommonAction.init(CommonAction.java:110)
2010-11-17 09:28:08,227 [main] INFO org.springframework.web.filter.CharacterEncodingFilter – Initializing filter ‘CharacterEncodingFilter’

 根據日志格式,需要將11-17的09:25:55 和09:28:08 之間的日志截取出來,。


使用sed命令如下:

sed -n '/2010-11-17 09:25:55/,/2010-11-17 09:25:55/p’  logfile

這樣可以精確地截取出來某個時間段的日志。

但是問題又來了,由於日志文件巨大,不能去vi打開文件。

根據之前看到過的日志格式,使用正則表達式。

sed -n ‘/2010-11-17 09:[0-9][0-9]:[0-9][0-9]/,/2010-11-17 16:[0-9][0-9]:[0-9][0-9]/p’  logfile

如果沒有問題的話,上面就能篩選出指定的時間段的日志。

工作實例:

09:20:46,408  INFO p6spy:? - 2016-03-03 09:20:46,408
09:20:46,408  INFO p6spy:? - 2016-03-03 09:20:46,408
09:20:46,418  INFO p6spy:? - 2016-03-03 09:20:46,418

sed -n '/2016-03-03 09:20:41/,/2016-03-03 09:21:00/p'  logfile
或
sed -n '/09:20:41/,/09:21:00/p'  logfile

以上兩種方式都可以進行實現獲取指定時間段

 

 

shell統計實例

1.用shell統計訪問日志里每個ip訪問次數

截取某個時間段日志--》統計IP數量,並放至一個文件A中--》循環統計文件A中每個IP的訪問次數

 [root@qunar logs]# cat a.sh 
#!/bin/bash
#將28/Jan/2015全天的訪問日志放到a.txt文本
cat access.log |sed -rn '/28\/Jan\/2015/p' > a.txt 
#統計a.txt里面有多少個ip訪問
cat a.txt |awk '{print $1}'|sort |uniq > ipnum.txt
#通過shell統計每個ip訪問次數
for i in `cat ipnum.txt`
do 
iptj=`cat  access.log |grep $i | grep -v 400 |wc -l`
echo "ip地址"$i"在2015-01-28日全天(24小時)累計成功請求"$iptj"次,平均每分鍾請求次數為:"$(($iptj/1440)) >> result.txt
done

 

統計接口訪問量

#!/bin/bash 
cd /etc/nginx/logs/old/
for i in  `seq 1 30`
do
dt=`date -d  "$i day ago"  +%Y%m%d`
cd  ${dt}
line=`cat *_sl.senseyun.com-getTime.log |wc -l` 
echo ${dt}:XX訪問量 "${line}"
cd ../
done

統計一個網段以及相應區段存活和宕機的ip

指定時間段增量統計nginx日志不同接口的訪問量

shell腳本分析 nginx日志訪問次數最多及最耗時的頁面(慢查詢)

shell腳本實現的網站日志分析統計(可以統計9種數據)

 

nginx日志

#根據訪問IP統計UV
awk '{print $1}' access.log|sort | uniq -c |wc -l

#統計訪問URL統計PV
awk '{print $7}' access.log|wc -l

#查詢訪問最頻繁的URL
awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more

#nginx日志統計獨立ip的個數:
awk '{print $1}' /path-to-log-dir/access.log | sort | uniq | wc -l

#查詢訪問最多的前10個ip
awk '{print $1}' /path-to-log-dir/access.log | sort | uniq -c | sort -nr | head -10

#查看某段時間的
grep "2012:0[3-6]" nginx.log |

pv:cat  nginx.log| sed -n /`date "+%d\/%b\/%Y"`/p |awk '{print $7}' |sort|wc -l

uv:cat  nginx.log| sed -n /`date "+%d\/%b\/%Y"`/p |awk '{print $1}' |sort|uniq -c |wc -l

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM