日志分級概念
所謂日志分級,就是將日志按照不同的層次,有選擇的輸出。
參考一些高級語言的分級日志設計,我們根據對程序運行信息的類型把控,可以把日志分為5個級別DEBUG、INFO、WARN、ERROR、FATAL。
- DEBUG:主要用于程序開發測試階段的打印輸出,用于驗證程序的設計邏輯是否滿足上層應用的設計需求,在經過測試檢驗后的發布程序可以把它關掉。
- INFO:這個級別的打印輸出是用來告訴測試人員或者開發人員一些提示的信息
- WRAN:這是一種警告的打印輸出,它一般是用來輸出諸如用戶輸入錯誤的數據之類的警告打印,這個級別的打印輸出在程序發布后也建議保留,以方面后期程序的維護追蹤。
- ERROR:運行出錯的打印,這個級別的打印在發布的軟件不可關閉,否則無法從發布軟件中獲取一些反饋信息來指導我們新的程序優化設計。
- FATAL :程序運行遇到這種級別的問題,很難修復,一般伴隨著程序的閃退或重啟,此時FATAL ERROR的打印則非常關鍵了,可以幫助我們定位到程序跑飛的原因,FATAL ERROR級別的打印在任何時刻都不可以關閉。
為什么要有日志分級?
一個好的日志分級設計,有助于我們快速定位問題,主要是方便后續開發和維護。在設計軟件的時候,可以根據問題出現的輕重緩急,有決策的去添加分層信息,在必要的時候有針對性的打開和關閉一些日志。
如何設計?
目前有兩種粗淺的設計策略,一種是或的關系,即各個日志等級彼此獨立,可以單獨打開關閉;一種是順序打印,根據設置打印等級,低于或者高于這個等級的才打印。
兩種沒有孰好孰壞,根據需要選擇合適策略即可。本文將以后者介紹。
設置打印級別
/*module_debug.h*/
/*1.設置打印級別*/
enum{
LOG_LEVEL_NONE,
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR,
LOG_LEVEL_FATAL,
};
/*2.log打印重寫*/
voidlog_fun(intlevel,constchar*opt,constchar*tag,intline,constchar*func,constchar*fmt,...);
/*3.各打印級別宏*/
/*
*@LOG_DBG
*/
#defineLOG_DBG(tag,fmt,...)
log_fun(LOG_LEVEL_DEBUG,"D",tag,__LINE__,__func__,fmt,##__VA_ARGS__)
/*
*@LOG_INFO
*/
#defineLOG_INFO(tag,fmt,...)
log_fun(LOG_LEVEL_INFO,"I",tag,__LINE__,__func__,fmt,##__VA_ARGS__)
/*
*@LOG_WARN
*/
#defineLOG_WARN(tag,fmt,...)
log_fun(LOG_LEVEL_WARN,"W",tag,__LINE__,__func__,fmt,##__VA_ARGS__)
/*
*@LOG_ERR
*/
#defineLOG_ERR(tag,fmt,...)
log_fun(LOG_LEVEL_ERROR,"E",tag,__LINE__,__func__,fmt,##__VA_ARGS__)
/*
*@LOG_FATAL
*/
#defineLOG_FATAL(tag,fmt,...)
log_fun(LOG_LEVEL_FATAL,"F",tag,__LINE__,__func__,fmt,##__VA_ARGS__)
注釋:... 和 __VA_ARGS__.省略點表示可變參數,__VA_ARGS__表示可變參數的宏,是C99規范中新增的,用來替換宏定義中的可變參數(...); ##運算符將兩個宏參數連接在一起。##__VA_ARGS__ 這里主要是為了解決當__VA_ARGS__為空時編譯問題,使用##防止編譯出錯。
根據打印級別控制輸出范圍
/*module_debug.c*/
#include
#include
#include
#include
#include
#include
#include
intg_current_dbg_level=LOG_LEVEL_DEBUG;
voidlog_fun(intlevel,constchar*opt,constchar*tag,intline,constchar*func,constchar*fmt,...)
{
if(level>g_current_dbg_level){
charmsg_buf[20*1024];
va_listap;
va_start(ap,fmt);
sprintf(msg_buf,"%s/%s(%d):%s()",opt,tag,line,func);
vsprintf(msg_buf+strlen(msg_buf),fmt,ap);
fprintf(stderr,"%s
",msg_buf);/*輸出到標準輸出*/
va_end(ap);
}
}
/*設置打印級別*/
voidModuleDebugInit(intlevel)
{
g_current_dbg_level=level;
}
測試
/*main.c*/
#include
#defineTAG"test"
intmain(intargc,char*argv[])
{
LOG_DBG(TAG,"log_debug%d
",LOG_LEVEL_DEBUG);
LOG_INFO(TAG,"log_info%d
",LOG_LEVEL_INFO);
LOG_WARN(TAG,"log_warn
");
LOG_ERR(TAG,"log_err
");
return0;
}
輸出打印信息:
I/test(61):main()log_info2
W/test(62):main()log_warn
E/test(63):main()log_err
其中I表示INFO、W表示WARN、E表示ERROR;緊接著跟著模塊(test),也可以是文件名;然后是行號、函數名,最后是打印信息。
當然具體打印信息和風格用戶可以根據需要,自行設計。
審核編輯 :李倩
-
程序
+關注
關注
117文章
3787瀏覽量
81072 -
嵌入式軟件
+關注
關注
4文章
240瀏覽量
26651 -
日志
+關注
關注
0文章
138瀏覽量
10648
原文標題:嵌入式軟件框架中一定不能缺少的日志管理系統的設計與實現
文章出處:【微信號:嵌入式應用研究院,微信公眾號:嵌入式應用研究院】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論