在我們嵌入式開發(fā)中,打印日志是最常用的一種調(diào)試手段。合理地打印日志,可以幫助我們快速地分析問題。
本篇文章我們來匯總一些嵌入式打log的一些規(guī)則。
1、什么操作下加日志?
(1)錯誤處理
對于不能恢復的嚴重錯誤,日志內(nèi)容應(yīng)詳細到足以幫助定位問題,但同時不應(yīng)該包含敏感信息。比如申請內(nèi)存失敗時使用錯誤(Error)級別加上日志信息。
(2)一些關(guān)鍵性的操作
一些很關(guān)鍵地處理,無論是正常情況或者異常情況都要打印日志。比如wifi打開時要有對應(yīng)的日志信息。
(3)系統(tǒng)的打開、關(guān)閉
記錄系統(tǒng)啟動和關(guān)閉過程中的關(guān)鍵步驟有助于分析系統(tǒng)初始化是否正確,或者系統(tǒng)是否正常關(guān)閉。
(4)性能監(jiān)控
日志可以記錄系統(tǒng)運行的關(guān)鍵性能指標,如CPU和內(nèi)存使用率、IO操作等,以便進行系統(tǒng)性能分析和優(yōu)化。
(5)關(guān)鍵數(shù)據(jù)
一些關(guān)鍵數(shù)據(jù)需要打印,很多功能上的問題大多直接與數(shù)據(jù)進行掛鉤。
(6)通信日志
對于需要與外部設(shè)備或網(wǎng)絡(luò)通信的嵌入式系統(tǒng),記錄通信日志可以幫助分析和調(diào)試通信協(xié)議或數(shù)據(jù)交換的問題。
(7)記錄用戶行為
在需要分析用戶如何與嵌入式設(shè)備交互的情況下,記錄用戶行為的日志會非常有幫助。
(8)if、switch
分支判斷中,各執(zhí)行分支需要加上對應(yīng)的日志信息,可以幫助我們準確地知道程序執(zhí)行的走向。
(9)程序崩潰時的信息
比如,Linxu下應(yīng)用進程崩潰時的調(diào)用堆棧信息。
#include#include #include #include voidfunc0(void) { printf("Thisisfunc0 "); int*p=NULL; *p=1234; } voidfunc1(void) { printf("Thisisfunc1 "); func0(); } voidfunc2(void) { printf("Thisisfunc2 "); func1(); } voiddump(intsigno) { void*array[100]; size_tsize; char**strings; size=backtrace(array,100); strings=backtrace_symbols(array,size); printf("Obtained%zdstacks. ",size); for(inti=0;i
2、功能模塊標簽
項目中肯定會劃分有多個模塊,可以給各個模塊標記一個模塊標簽字符串,包含在日志條目里。這樣我們就可以在日志文件里通過模塊標簽來篩選某個模塊的日志,提高我們定位問題的效率。
比如:
//app_wifi.c #defineLOG_TAG"[wifi_module]" #defineLOG_D(fmt,arg...)LOG_D_TAG(LOG_TAG,fmt,##arg) LOG_D("hellowifimodule");
輸出:
[wifi_module]hellowifimodule
3、模塊日志開關(guān)
設(shè)置模塊日志開關(guān),可以方便我們調(diào)試、分析問題時,縮小分析范圍。當我們的函數(shù)設(shè)計有多個功能函數(shù)模塊的時候,當某個模塊出現(xiàn)問題時,這個時候我們只是關(guān)心此模塊,那么可以先把其他模塊的日志功能關(guān)閉掉,只是打開關(guān)心模塊的日志。
如:
//module1.c #include"module1.h" #ifMODULE1_LOG_SWITCH #defineLOG_MODULE1(fmt,args...)DBG_PRINTF(fmt,##args) #else #defineLOG_MODULE1(fmt,args...) #endif //module2.c #include"module2.h" #ifMODULE2_LOG_SWITCH #defineLOG_MODULE2(fmt,args...)DBG_PRINTF(fmt,##args) #else #defineLOG_MODULE2(fmt,args...) #endif //config.h #defineMODULE1_LOG_SWITCH0 #defineMODULE2_LOG_SWITCH1
4、時間戳
日志應(yīng)包含時間戳,可以方便地查看某段代碼的執(zhí)行時間、確定問題發(fā)生的具體時間。時間戳最好能精確到微秒/毫秒。
5、日志級別
使用不同的日志級別可以幫助篩選和控制輸出的信息量。
常見的日志級別包括:
錯誤(Error):程序無法運行或嚴重問題。
警告(Warning):可能的問題,程序可以繼續(xù)運行。
信息(Info):程序運行狀態(tài)信息。
調(diào)試(Debug):詳細的調(diào)試信息,包括變量值和程序流程。
詳細(Verbose):非常詳細的信息,用于深入調(diào)試。
6、格式統(tǒng)一
為了使日志易于閱讀,所有日志應(yīng)保持一致的格式。
日志里常包含的固定信息有:
文件名
行號
時間日期/時間戳
函數(shù)名
模塊名稱
進程ID
線程ID
可根據(jù)需要進行組合。如:
[2024-01-1411:12:30.666][wifi_module][func:wifi_init]
7、過濾控制
使用日志動態(tài)過濾控制功能可以動態(tài)地調(diào)整日志地輸出,但前提是項目使用地日志組件具備這樣的能力。比如EasyLogger(https://github.com/armink/EasyLogger)。
8、Release/Debug開關(guān)
由于日志打印可能占用不少系統(tǒng)資源,應(yīng)當注意其對性能的影響。在Release版本中,可能需要減少日志輸出或者去掉一些不必要的日志,需要一個開關(guān)來進行切換。
9、封裝日志接口
嵌入式中,日志的輸出大多數(shù)情況下會輸出到串口終端。但也有一些場景,需要把日志輸出到屏幕、網(wǎng)絡(luò)設(shè)備、定制化的上位機等場景。需要留出對應(yīng)接口,方便靈活切換。
審核編輯:劉清
-
嵌入式開發(fā)
+關(guān)注
關(guān)注
18文章
1028瀏覽量
47564 -
上位機
+關(guān)注
關(guān)注
27文章
941瀏覽量
54792 -
linxu
+關(guān)注
關(guān)注
0文章
7瀏覽量
2550
原文標題:嵌入式中,日志調(diào)試法的一些規(guī)則!
文章出處:【微信號:麥克泰技術(shù),微信公眾號:麥克泰技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論