之前我我的的觀念是,在線上運行的東西儘可能不要記什麼流水日誌。php
可是後來我變了,發如今線上記日誌是一個絕對有必要的東西,尤爲是在當下很流行的微服務的推進下,沒有日誌的幫助,猶如一個睜眼瞎,排查問題基本靠猜,這可不行。java
那就打印記錄每次的訪問日誌,尤爲是訪問接口時的參數及返回數據和耗費時間等,這是對本身將問題拋給上層及性能優化的依據。可是日誌量應該是很是大的,必定要注意及時清理。git
那麼問題來了,當發現問題時,如何快速定位到錯誤的地方就很重要了。docker
日誌樣例以下(某次訪問的產生的日誌):數據庫
[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.shoujidai.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 ----
問題一、我想查看有多少獨立訪問了這臺機器?(可能有多天的訪問日誌)api
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
問題二、發現某個外網接口慢了,怎樣查看該接口慢的地方都有哪些?bash
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 #統計總共有多少地方
問題三、假設有錯誤產生,可是不肯定訪問是否訪問到該機器,是否能夠同時看到訪問日誌與錯誤日誌?服務器
tail -f access_log error_log # 將訪問日誌與錯誤日誌同時動態打印出來,若是同時出現則證實訪問到該機器且可查看錯誤
問題四、如何清理日誌?用crontab運行定時cron腳本。crontab -e網絡
FilePath=/data/log find FilePath -mtime +3 -name '*.log' -exec rm -rf {} \;
問題五、臨時檢查某接口是否通暢?使用curl命令
curl -i http://coe.test.com:8080/micro_site/api/user/info #加-i參加可返回頭信息,更多命令可查看幫助文檔 ping coe.test.com #直接看該域名是否可用 telnet coe.test.com #若是須要,也可使用telnet命令
問題六、使用docker容器進行管理測試環境,一些簡單的docker 命令應該知曉
docker ps | grep myserver #查看docker 進程,過濾想要的行,如查看映射端口及徹底的鏡像名稱 docker exec -it myserver /bin/bash #進入本身的docker 容器
問題七、其餘技巧?
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異常,加內存或者優化代碼解決。