日志分級(jí)概念
所謂日志分級(jí),就是將日志按照不同的層次,有選擇的輸出。
參考一些高級(jí)語言的分級(jí)日志設(shè)計(jì),我們根據(jù)對(duì)程序運(yùn)行信息的類型把控,可以把日志分為5個(gè)級(jí)別DEBUG、INFO、WARN、ERROR、FATAL。
DEBUG:主要用于程序開發(fā)測(cè)試階段的打印輸出,用于驗(yàn)證程序的設(shè)計(jì)邏輯是否滿足上層應(yīng)用的設(shè)計(jì)需求,在經(jīng)過測(cè)試檢驗(yàn)后的發(fā)布程序可以把它關(guān)掉。
INFO:這個(gè)級(jí)別的打印輸出是用來告訴測(cè)試人員或者開發(fā)人員一些提示的信息
WRAN:這是一種警告的打印輸出,它一般是用來輸出諸如用戶輸入錯(cuò)誤的數(shù)據(jù)之類的警告打印,這個(gè)級(jí)別的打印輸出在程序發(fā)布后也建議保留,以方面后期程序的維護(hù)追蹤。
ERROR:運(yùn)行出錯(cuò)的打印,這個(gè)級(jí)別的打印在發(fā)布的軟件不可關(guān)閉,否則無法從發(fā)布軟件中獲取一些反饋信息來指導(dǎo)我們新的程序優(yōu)化設(shè)計(jì)。
FATAL :程序運(yùn)行遇到這種級(jí)別的問題,很難修復(fù),一般伴隨著程序的閃退或重啟,此時(shí)FATAL ERROR的打印則非常關(guān)鍵了,可以幫助我們定位到程序跑飛的原因,F(xiàn)ATAL ERROR級(jí)別的打印在任何時(shí)刻都不可以關(guān)閉。
為什么要有日志分級(jí)?
一個(gè)好的日志分級(jí)設(shè)計(jì),有助于我們快速定位問題,主要是方便后續(xù)開發(fā)和維護(hù)。在設(shè)計(jì)軟件的時(shí)候,可以根據(jù)問題出現(xiàn)的輕重緩急,有決策的去添加分層信息,在必要的時(shí)候有針對(duì)性的打開和關(guān)閉一些日志。
如何設(shè)計(jì)?
目前有兩種粗淺的設(shè)計(jì)策略,一種是或的關(guān)系,即各個(gè)日志等級(jí)彼此獨(dú)立,可以單獨(dú)打開關(guān)閉;一種是順序打印,根據(jù)設(shè)置打印等級(jí),低于或者高于這個(gè)等級(jí)的才打印。
兩種沒有孰好孰壞,根據(jù)需要選擇合適策略即可。本文將以后者介紹。
設(shè)置打印級(jí)別
/*module_debug.h*/ /*1.設(shè)置打印級(jí)別*/ 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.各打印級(jí)別宏*/ /* *@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__.省略點(diǎn)表示可變參數(shù),__VA_ARGS__表示可變參數(shù)的宏,是C99規(guī)范中新增的,用來替換宏定義中的可變參數(shù)(...); ##運(yùn)算符將兩個(gè)宏參數(shù)連接在一起。##__VA_ARGS__ 這里主要是為了解決當(dāng)__VA_ARGS__為空時(shí)編譯問題,使用##防止編譯出錯(cuò)。
根據(jù)打印級(jí)別控制輸出范圍
/*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);/*輸出到標(biāo)準(zhǔn)輸出*/ va_end(ap); } } /*設(shè)置打印級(jí)別*/ voidModuleDebugInit(intlevel) { g_current_dbg_level=level; }
測(cè)試
/*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表示W(wǎng)ARN、E表示ERROR;緊接著跟著模塊(test),也可以是文件名;然后是行號(hào)、函數(shù)名,最后是打印信息。
當(dāng)然具體打印信息和風(fēng)格用戶可以根據(jù)需要,自行設(shè)計(jì)。
審核編輯:劉清
-
C語言
+關(guān)注
關(guān)注
180文章
7610瀏覽量
137231
原文標(biāo)題:C語言日志分級(jí)如何設(shè)計(jì)?
文章出處:【微信號(hào):技術(shù)讓夢(mèng)想更偉大,微信公眾號(hào):技術(shù)讓夢(mèng)想更偉大】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論