我們平時查日志,在測試環境,日志文件只有幾個的情況下,我們可以通過找時間接近的文件然后根據關鍵詞定位報錯位置,大不了都查一遍,這都可以忍受。但是在實際的生產環境下,服務器集群部署,每天的日志非常多非常多,每台機器都會有幾十個甚至多達上百個、數百個日志文件產生。遇到問題需要查詢日志時,你會發現如果一個個文件去查,你會崩潰掉。因為這是很費時的重復性工作,而且也不一定能查到。
為了解決這種問題,大多數人會去編寫shell腳本,用來檢索日志文件,這樣能篩掉很多無用文件,減輕查日志的工作量。服務器集群部署下,同樣適用,我們可以在每台機器同樣的目錄下放一份腳本文件,然后通過xshell對所有遠程會話執行腳本,所有連接到的機器就都能執行腳本了。
我們快速定位問題的前提是首先定位用戶的操作記錄信息在哪個幾個文件,然后在這個幾個文件中找到報錯的堆棧信息進行分析,從而找到出錯的原因。
縮小報錯文件范圍,是查日志提高效率的前提。
下面這段代碼是就是簡單的篩選日志文件的shell腳本。如果你懂shell編程,可以在此基礎上修改,添加你自己需要的功能。
#!/bin/bash #日期$1 關鍵詞$2 date=$1; key_word=$2; #日志文件的基礎目錄 base_path=/home/logs/application/ #基礎目錄+指定的目錄 files_path="$base_path$date/" #判斷指定目錄下是否有文件 f_count=$(ls $file_path|grep "^-"|wc -l) #文件個數為0,退出腳本 if [ $f_count -eq 0 ] then echo "目錄下沒有文件" exit fi #否則繼續執行 #目錄下的所有文件 files=$(ls $files_path) #標志位 找到相關日志后,把tmp下的之前的先刪除 只執行一次刪除 flag=0 echo "start" for file in $files do echo "find in $file" #文件的全路徑 f_p="$files_path$file" #統計文件中Word的個數 count=$(grep -c $key_word $f_p) #打印包含key_word cat $f_p | grep $key_word if [ $count -gt 0 ] then #找到后把tmp清了 if [ $flag -eq 0 ] then rm -f tmp/* fi #標志位置為1,清除只執行一次 flag=1 #拷貝包含關鍵詞的文件到tmp下 cp $f_p tmp/$file fi done echo "end"
其中base_path是日志文件的根目錄,假設我們的日志都是在/home/logs/application/下,每天生成一個日期命名的文件夾放當天的的日志文件,2019-04-18,切割的多個日志文件除固定前綴以外加上索引。
如/home/logs/application/2019-04-18/application_20190418_0.log和/home/logs/application/2019-04-18/application_20190418_1.log
假如截止到今天查詢日志時服務器產生了80個文件,我要查某個用戶提的工單反饋,我們日志里都會打印用戶手機號,那么我們可以這樣:
sh find.sh 2019-04-18 18300000000
這樣腳本會拷貝用戶18300000000的所有操作記錄的日志文件到tmp目錄里(與shell腳本同目錄),然后我們對tmp下的日志進行操作。
在日志太多的情況下,日志可能會被打包壓縮,我們可以改下腳本,多一步,先把壓縮后的解壓縮再進行查找操作。
有的公司會有更高級的做法,例如elk日志分析平台,我們在elk上查日志更加方便,可視化的界面,可選擇性更強,多查詢條件等。