天天看點

截取與分析日志檔案的特定行數的操作



在進行作業系統和資料庫系統管理時,經常會遇到在日志檔案中查找某個字元,或者按照時間截取某個時間段的日志進行分析。

今天早上就遇到一個MySQL資料庫上的問題,mysql資料庫在0-3點的時候,資料庫會話連接配接,tps,cpu和iowait等都比平時大了許多。

為了定位這個時間段内,到底發生了那些慢查詢,消耗了資源,就需要在slow.log慢查詢日志進行查詢,截取和分析。

在處理過程中,對幾種常用的日志截取方法進行了彙總和測試:

截取日志段的的方法彙總與測試

方式一: 确定時間段的行号,使用head和tail指令截取 搜尋時間: Time: 151212 00:00:00   先到gg,到檔案最前面,然後搜尋 /Time: 151212  ,得到: 1979016 # Time: 151212  0:00:15

檔案總行數為: # wc -l slow-query-169-1212.log 1999422 slow-query-169-1212.log 1999422                                 limit 0,20;

然後在到檔案最後面,G, 搜尋4點之後開始的檔案  /Time: 151212  4   ,得到: 1987392 # Time: 151212  4:00:05

确定需要查詢的時間段行号後,使用head和tail指令進行截取: >>> 1987392 - 1979016; 8376

需要截取的日志,最後行号為 1979016,想用head 指令,然後在用tail指令截取最後的 8376 行即可,指令為: head -n 1979016 slow-query-169-1212.log | tail -n 8376   > slow-query-169-1212_00-03.log

方式二: 确定時間段的行号,使用sed指令截取 截取 151212  0-3點之間的慢查詢日志: sed -n '1979016,1987392p' slow-query-169-1212.log  > slow-query-169-1212_00-03.log

>>> 1987392 - 1979016; 8376 該部分檔案,應該有 8376 行資料;确認正常;

方式三:确定時間段行号後,使用awk指令截取 截取 151212  0-3點之間的慢查詢日志: awk -F"\n" '{if(NR>=1979016&&NR <=1987392)print $0 }' slow-query-169-1212.log  > slow-query-169-1212_00-03.log

方式四:不需先确定行号,直接用sed取出日志段 slow log都是以  # Time: 151212  0:00:15 開頭,直接用sed 取出其中的日志: sed -n '/^# Time: 151212  0/,/^# Time: 151212  4/p' slow-query-169-1212.log > part.log    --這樣的效果,就和剛才上面的效果相同,取出了0 -3 點之間的資料

如果是想取出 151211 這一天的資料,則指令為: sed -n '/^# Time: 151211/,/^# Time: 151212/p' slow-query-169-1212.log > part.log        --取出了151211 這一天的日志

注意,使用sed 時,兩行之間的選擇項一定要對應,不然結果就不是想要的結果了: sed -n '/^# Time: 151212/,/^# Time: 151212  4/p' slow-query-169-1212.log > part.log     --前後兩個時間點不同,搜尋的是全部  # Time: 151212開頭的

使用pt工具對截取的日志進行分析 分析這段時間的日志的指令如下: /usr/local/pt/bin/pt-query-digest  /data/bbs/slow-query-169-1212_00-03.log > /data/bbs/slow-query-169-1212_00-03-report.log

這是預設的分析和排序方法,可以根據需求,選擇其他pt報告分析方法

注1 vim中兩種查詢方式: 指令模式下,按‘/’,然後輸入要查找的字元,Enter。?和/的差別是,一個向前(下)找,一個向後(上)。 另外,‘*’可以查找目前光标下的word(完全符合),‘g*’則部分符合,以#代替*表示向後(上)找

注2 幾種檔案處理方法的簡單舉例: sed是按行處理的,不會将整個檔案加載到記憶體中,可以放心使用  要切出從2012-02-09到2012-09-10的所有資料行,(假設你的日志檔案以yyyy-MM-dd的日期格式開頭)隻需要: sed -n '/^2012-02-09/,/^2012-09-10/p' whole.log > part.log

無論怎麼樣你都必須使用某一個程式把這個檔案讀出來,并且用一定的規則來加以過濾。 在Linux中,使用cat和grep對檔案進行操作已經可以說是最經濟合理的了。 占用一定的系統資源是肯定的,具體的話跟你使用的cat,grep以及linux核心都有一定關系,是以可能會略有不同。 一般不要在系統裡出現那麼大的日志檔案,最好在一開始就做好日志的大小限制以及合理的日志轉儲和備份。

顯示檔案的第2到第6行 sed -n '2,6p' file

需要加-n參數. head -n 6 file|tail -n 4

awk 也能達到要求 awk -F"\n" '{if(NR>=2&&NR <=6)print $0 }' file