日志快速篩選 之 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異常,加內存或者優化代碼解決。


免責聲明!

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



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