打log的原則
- 異常分支或錯(cuò)誤處理一定要打log
- 重大操作時(shí)一定要打log,下面打log場(chǎng)景會(huì)講述
log格式的原則
1、時(shí)間戳必須有,最好能夠精確到微秒精確到秒的時(shí)間戳,相信很多人都熟悉,這能夠確認(rèn)問題的時(shí)間和系統(tǒng)uptime的對(duì)比,能夠進(jìn)一步還原問題的場(chǎng)景。至于到微秒,在多線程程序下,如果進(jìn)程停止響應(yīng),可以從日志時(shí)間看是否死鎖。一般格式:
[2017-01-09 12:16:30.541]
2、打log位置的文件名和代碼行數(shù)這個(gè)不用說,用于定位問題根源。其實(shí)最重要是防止扯皮。因?yàn)?a target="_blank">程序員大多喜歡copy-paste,如果你不加文件名和行數(shù),某程序員copy了你的代碼,修改了點(diǎn),出錯(cuò)了,到時(shí)候把你拉下水。一般格式:
[2017-01-09 12:16:30.541][network.c:541]
3、有進(jìn)程id有些log機(jī)制在進(jìn)程重啟時(shí),不會(huì)重新生成一個(gè)日志文件,而是直接在同一個(gè)日志文件后面添加日志?;蛘?,有時(shí)候同一程序的多個(gè)進(jìn)程同時(shí)運(yùn)行,可能也會(huì)寫入到同一個(gè)日志文件。一般格式:
[2017-01-09 12:16:30.541][network.c:541][pid=15529]
4、有線程id在多線程程序,如果不加線程id,很難追溯程序的行為。一般格式:
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345]
5、有日志的級(jí)別日志是反映問題的,有不同緊急程序的問題,自然有不同的日志級(jí)別。一般采用Error,Warning,Info,Debug。定義不同級(jí)別,也可以方便在日志查找問題來源。一般格式:
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]
打log的場(chǎng)景1、申請(qǐng)內(nèi)存時(shí),失敗的話,要把申請(qǐng)大小打印出來以前我申請(qǐng)內(nèi)存失敗也是簡(jiǎn)單地打?。?/span>
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]Failedtoallocatememory
后來在重構(gòu)時(shí)遇到一個(gè)問題:進(jìn)程跑的時(shí)間一久,大概一天多,別的程序向它發(fā)消息都會(huì)收到失敗響應(yīng),在日志里就是一大堆內(nèi)存失敗的消息"Failed to allocate memory"。用"free"命令來看,物理內(nèi)存還有好幾G空閑,而用“top”命令來看,該進(jìn)程也只是占700M內(nèi)存。當(dāng)時(shí)我就懷疑是不是內(nèi)存碎片導(dǎo)致。于是我把申請(qǐng)內(nèi)存的大小也打印出來,就收到一堆這樣的:
[2017-01-09 12:16:30.541][network.c:541][pid=15529][thread=0x12345][Error]Failed to allocate memory of size 65536
[2017-01-09 12:16:30.588][network.c:541][pid=15529][thread=0x12345][Error]Failedtoallocatememoryofsize1048576
當(dāng)時(shí)就看那些代碼引用的數(shù)據(jù)結(jié)構(gòu),最小也有64K,大的16M都有,基本一個(gè)結(jié)構(gòu)包括很多個(gè)大數(shù)組。當(dāng)時(shí)就把那些數(shù)組全改為指針,再進(jìn)一步申請(qǐng),代碼繁瑣了,但這種問題再也不會(huì)出現(xiàn)。再看bug系統(tǒng),原來這個(gè)問題存在很多,在其它程序也存在,當(dāng)時(shí)都找不到根因,只是用過一段時(shí)間重啟進(jìn)程來解決2、 函數(shù)參數(shù)非空判斷時(shí),要打印日志原因不說,看對(duì)比:之前:
if ( ( pInfo == NULL ) || ( pHandler == NULL ) )
{
log( ERROR, "invalid arguments" );
}
之后:
if ( ( pInfo == NULL ) || ( pHandler == NULL ) )
{
log( ERROR, "invalid arguments:(pInfo, pHandler )=(%p,%p)",
pInfo, pHandler );
}
3、加載和卸載模塊,無論是正常還是異常情況都要打印畢竟這些操作大多都是一次性操作。對(duì)性能影響不大。
[2017-01-09 12:16:30.588][modules.c:54][pid=15529][thread=0x12345][Error]Failedtoloadmodulelibftp.so,error=modulealreadyloaded
4、操作文件目錄時(shí),失敗要把文件名和錯(cuò)誤碼打印出來如:
[2017-01-09 12:16:30.588][config.c:120][pid=15529][thread=0x12345][Error]Failedtoopenfileconf/ftp.xml,errno=(13:Permissiondenied)
假設(shè)這個(gè)錯(cuò)誤導(dǎo)致進(jìn)程初始化失敗,且環(huán)境在客戶那邊,維護(hù)人員就可以確認(rèn)并自己解決這個(gè)問題。5、操作socket時(shí),把IP,端口號(hào)或路徑名(Unix socket )和錯(cuò)誤碼打印出來如:
[2017-01-09 12:16:30.588][network.c:541][pid=15529][thread=0x12345][Error]Failedtoconnecttohost(10.17.128.10:9981),errno=(111:Connectionrefused)
假設(shè)在客戶環(huán)境出錯(cuò),維護(hù)人員可以根據(jù)日志來確認(rèn)10.17.128.10這臺(tái)機(jī)器是否在線,是否開啟了相應(yīng)的服務(wù),或者服務(wù)是開啟了,可能只是端口配置錯(cuò)了(這種情況是扯皮最多的)6、操作數(shù)據(jù)庫時(shí),把相應(yīng)操作的IP,端口,庫,用戶名,sql語句和錯(cuò)誤打印出來如:
[2017-01-09 12:16:30.588][dbmgr.c:781][pid=15529][thread=0x12345][Error]user tiger failed to operate in host (10.17.128.10:3365) with db test, sql="select * from users", error="no table users exists"
在客戶環(huán)境下,維護(hù)人員可以通過命令行來驗(yàn)證這些問題,來確定問題??赡苡腥藭?huì)考慮安全性,畢竟在日志中把IP,端口,庫,用戶名都暴露出來了,這樣好像不妥。但如果是從事過通信行業(yè)的網(wǎng)上問題維護(hù),就知道,可維護(hù)性比這種細(xì)節(jié)的安全性還要重要。7、創(chuàng)建新進(jìn)程時(shí),需要把程序名,參數(shù)和錯(cuò)誤碼打印出來如:
[2017-01-09 12:16:30.588][process.c:154][pid=15529][thread=0x12345][Error]failed to execute program "iptables -L", errno=(2:No such file or directory)
往往在客戶環(huán)境,由于運(yùn)維人員水平參差不齊,可能誤操作或漏操作,導(dǎo)致文件缺失或權(quán)限出錯(cuò),這種錯(cuò)誤在公司的模擬環(huán)境根本不會(huì)出現(xiàn)。如果日志夠詳細(xì),能夠減少很多工作量。8、解析文件時(shí),需要把文件名,字段,行號(hào)打印出來如:
[2017-01-09 12:16:30.588][config.c:120][pid=15529][thread=0x12345][Error]Failed to parse file conf/ftp.xml, line:20, tag <host> is not closed
結(jié)語上面的原則,基本是每一條是血的教訓(xùn)。以前在H時(shí)見得太多因?yàn)槿罩静蝗珜?dǎo)致的麻煩,前方的客戶經(jīng)理不斷向客戶懇求寬限時(shí)間,維護(hù)人員不斷地在客戶環(huán)境找出蛛絲馬跡,后方領(lǐng)導(dǎo)也不斷地調(diào)配資源來跟蹤問題,后方測(cè)試人員不斷地測(cè)試,嘗試問題復(fù)現(xiàn),后方開發(fā)人員就不斷地看代碼。在Z也見過因?yàn)槿罩静蝗?,?dǎo)致被客戶罰錢次數(shù)過多,整個(gè)產(chǎn)品都虧損了。像?@帝都鐵匠 說的“感覺學(xué)會(huì)log,程序就算入門了”。
-
程序
+關(guān)注
關(guān)注
117文章
3814瀏覽量
81858 -
Log
+關(guān)注
關(guān)注
0文章
15瀏覽量
11412 -
線程
+關(guān)注
關(guān)注
0文章
507瀏覽量
19923
原文標(biāo)題:感覺學(xué)會(huì)log,程序就算入門了
文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
FPGA入門容易,關(guān)鍵是怎么進(jìn)階!
教大家如何看懂電路圖
討論labview如何算入門?
總結(jié)大佬經(jīng)驗(yàn),如何學(xué)習(xí)STM32?(入門、進(jìn)階)
單片機(jī)開發(fā)怎么才算入門了
輕松入門開發(fā)ARM程序

輕松入門開發(fā)ARM程序
云計(jì)算入門指南
LOG112,LOG2112,pdf(Precision Logarithmic and Log Ratio Ampli
LOG101/LOG104偏流調(diào)零電路

通信原理易入門 上手 輕松學(xué)會(huì)現(xiàn)代通信原理

如何讓應(yīng)用程序感覺更快
基于Rust的Log日志庫介紹
Log4cpp優(yōu)勢(shì)及優(yōu)點(diǎn)

評(píng)論