天天看點

日志快速篩選 之 linux指令grep|uniq|wc|awk

  以前我個人的觀念是,線上上運作的東西盡量不要記什麼流水日志。

  但是後來我變了,發現線上上記日志是一個絕對有必要的東西,尤其是在當下很流行的微服務的推動下,沒有日志的幫助,猶如一個睜眼瞎,排查問題基本靠猜,這可不行。

  那就列印記錄每次的通路日志,尤其是通路接口時的參數及傳回資料和耗費時間等,這是對自己将問題抛給上層及性能優化的依據。但是日志量應該是非常大的,一定要注意及時清理。

  那麼問題來了,當發現問題時,如何快速定位到錯誤的地方就很重要了。

日志樣例如下(某次通路的産生的日志):

[2017-01-14 17:38:44]  New request@ip: 112.65.141.22
[2017-01-14 17:38:44]  New request@ip: 112.65.141.22 param: <xml><ToUserName><![CDATA[gh_27923assff]]></ToUserName> <FromUserName><![CDATA[osj3ut7w0VqGU-6k1WssdmAQPVU]]></FromUserName> <CreateTime>1484386723
</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[http://satwx.ddd.com/wap]]></Content> <MsgId>6375392430314143735</MsgId> </xml>
[2017-01-14 17:38:44]  cat@http://192.168.1.125:30008/eagleeye/monitor/logEvent @visit, msg=> New request@ip: 112.65.141.22 ...
[2017-01-14 17:38:44]  api begin: [get] http://192.168.1.11:40003/micsite/api/ss/microsite/1.1/wchat/getAcken?wchatName=wx477026f155386
[2017-01-14 17:38:44]  api end: cost: 0.0081648826599121 sec,return data: {"error":"4000063","msg":"無該公衆賬号的accessToken資訊 !","status":"0"}
[2017-01-14 17:38:44]  get token error [code:status 0]: {"error":"4000063","msg":"無該公衆賬号的accessToken資訊 !","status":"0"}
[2017-01-14 17:38:44]  api begin: [get] https://api.weixin.qq.com/cgi-bin/user/info?access_token=&openid=osj3ut7w0VqGU-6k1WHVi5mAQPVU&lang=zh_CN
[2017-01-14 17:38:44]  api end: cost: 0.08442211151123 sec,return data: {"errcode":41001,"errmsg":"access_token missing hint: [ohHxoa0723vr30!]"}
[2017-01-14 17:38:44]  get UnionId error: {"errcode":41001,"errmsg":"access_token missing hint: [ohHxoa0723vr30!]"}
[2017-01-14 17:38:45]  POST  https://a1.easemob.com/ddd/xyytest/token {"grant_type":"client_credentials","client_id":"YXA6895cUK3_EeW3YsEU_isqRQ","client_secret":"YXA61QdxmD9yvNcxd9zaHrcmFfTRZ3M"}
[2017-01-14 17:38:45]  return data: {"access_token":"YWMtf7ebhtFWEeaBVquozfw40QAAAA3A67AAAAAAHz3lxQrf8R5bdiwR4FZYgHzdwBPGgDdng322dddssvrzggb2_tQflF-cf4FEO07WzyZJuEQ","expires_in":4205288,"app
lication":"f3de5c50-adff-11e5-b762-c114fe2b2a45"} , cost: 0.19826197624207 sec
[2017-01-14 17:38:45]  POST  https://a1.easemob.com/dd/xyytest/messages {"target_type":"users","target":["custom"],"msg":{"type":"txt","msg":"http:\/\/satwx.test.com\/wap"},"from":"hx_callback","ext"
:{"weichat":{"visitor":{"source":"weixin","msgId":"6375392430314143735","openid":"osj3ut7w0VqGU-6k1WHVi5mAQPVU","mp":"wx812302f2923a0e2f","userNickname":null}}}}
[2017-01-14 17:38:45]  return data: {"action" : "post","application" : "f3de5c50-adff-11e5-b762-c114fe2b2a45", "path" : "/messages"} , cost: 0.15990281105042 sec
[2017-01-14 17:38:45]  output: (empty)
[2017-01-14 17:38:45]  ---- This time cost: 0.52057886123657 sec ----      

問題1、我想檢視有多少獨立通路了這台機器?(可能有多天的通路日志)

grep -n -E "\[2017-01-14 [0-9]{2}:[0-9]{2}:[0-9]{2}\] [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" *log | awk '{if(!ip[$3]++) print $3 " ===> " $1 " " $2 " "  $4;}' | sort | uniq | less      

  想要統計總共有多少ip時,隻需後接一個wc -l 的管道指令即可:

cat a.log | wc -l      

問題2、發現某個外網接口慢了,怎樣檢視該接口慢的地方都有哪些?

grep -A1 -n "api.weixin.qq.com/cgi-bin/" *.log | grep -v "api.weixin.qq.com" | awk '$6 > 5' | less     #grep -v 是将接口通路欄給去掉,隻留下時間記錄行,過濾出通路時間大于5秒的日志
. | wc -l  #統計總共有多少地方      

問題3、假設有錯誤産生,但是不确定通路是否通路到該機器,是否可以同時看到通路日志與錯誤日志?

tail -f access_log error_log   # 将通路日志與錯誤日志同時動态列印出來,如果同時出現則證明通路到該機器且可檢視錯誤      

問題4、如何清理日志?用crontab運作定時cron腳本。crontab -e

FilePath=/data/log
find FilePath -mtime +3 -name '*.log'  -exec rm -rf {} \;       

問題5、臨時檢查某接口是否通暢?使用curl指令

curl -i http://coe.test.com:8080/micro_site/api/user/info  #加-i參加可傳回頭資訊,更多指令可檢視幫助文檔
ping coe.test.com  #直接看該域名是否可用
telnet coe.test.com #如果需要,也可以使用telnet指令      

問題6、使用docker容器進行管理測試環境,一些簡單的docker 指令應該知曉

docker ps | grep myserver    #檢視docker 程序,過濾想要的行,如檢視映射端口及完全的鏡像名稱
docker exec -it myserver /bin/bash      #進入自己的docker 容器      

問題7、其他技巧?

netstat -tunlp          #檢視網絡端口監聽情況,以确定伺服器是否有問題
ps -ef | grep httpd    #檢視程序相關 pstree 更生動                
grep -F -f a.txt b.txt  #求檔案交集
sort a.txt b.txt | uniq -d  #求兩檔案交集
sort a.txt b.txt b.txt | uniq -u   #求兩檔案不重複的項      

說到日志篩選,其實隻是想定位到問題在哪裡,在這裡就多了幾句,以備後用吧!

對于php解釋型語言,調試起來相對友善,直接在伺服器上改掉進行嘗試即可,但是也有一個壞處就是沒有編譯器來給你檢查代碼,會隐藏一些文法錯誤。一般來說,将通路日志與錯誤日志一起列印會讓你快速解決問題。文法錯誤相對好解決,邏輯錯誤則需要定位代碼位置,仔細分析才能解決。

對于像java一類的編譯型語言,調試則相對麻煩一些。一般在改動很小或者一兩個檔案的時候,可以直接通過替換.class檔案的方式,重新開機伺服器進行快速調試,但是對于多個檔案的更改基本上就得重新打包上傳了。.war包的class檔案可以友善的通過ftp工作替換,而.jar包則麻煩些,需先将伺服器上的jar包下載下傳至本地,用壓縮工具打開後,直接替換class檔案後,再将整個jar包上傳即可。java的日志相對會比較大,是以清理檔案會更多或更頻繁。

使用svn, git等工具進行代碼管理很友善,但有時送出檔案修改時,容易忘記添加的檔案,多半會引起ClassNotFoundException,快速搞定。

對于NullPointerException異常,找到引發錯誤的行,觀察是哪個變量可能引起該錯誤,可能是接口響應,可能是資料庫問題。

對于OutOfMemoryError異常,加記憶體或者優化代碼解決。

不要害怕今日的苦,你要相信明天,更苦!

繼續閱讀