日志簡(jiǎn)述
C/CPP的日志工具也很多,在之前的項(xiàng)目中用過的有以下幾個(gè):zlog、spdlog、log4cpp等。
zlog之前也介紹過,這個(gè)日志工具我在使用的時(shí)候遇到過2個(gè)問題:
1.多線程輸出比較頻繁的時(shí)候,切換文件時(shí)程序會(huì)掛掉;
2.有的平臺(tái)下面,切換文件時(shí),程序掛掉再無法啟動(dòng),只能手動(dòng)刪除日志文件,或者不讓日志輸出到文件;
zlog使用是挺方便,也很快,就是有上面兩個(gè)問題,所以后來考慮換掉。
spdlog之前也介紹過。這個(gè)也挺好用,只需要包含頭文件即可,只是這個(gè)日志依賴于c++11,有些編譯器比較老,不支持,c語言也無法使用。
今天要介紹的這個(gè)日志是easylogger,這個(gè)是c語言的版本,所以c/c++都可以用,這個(gè)日志官方提供的demo和文檔比較全,我就不再多說了。
log4cpp的輸出方式不太喜歡……
EasyLogger簡(jiǎn)介
主要是對(duì)其源文件的使用做個(gè)調(diào)整。將對(duì)其源碼引用的操作單獨(dú)做了一個(gè)Makefile,這樣使用的時(shí)候只需要在項(xiàng)目代碼的Makefile里引用一下它的
Makefile即可:demo 的結(jié)構(gòu)如下:
.
├── easylogger
│ ├── easylogger ---- 移植修改文件
│ │ ├── inc
│ │ └── port
│ └── source_code ----- 源碼目錄
│ ├── inc
│ ├── obj
│ ├── plugins
│ │ ├── file
│ │ └── flash
│ ├── port
│ └── src
├── main.c-bak --- 測(cè)試主函數(shù)代碼
├── main.cpp --- 同main.c-bake
├── Makefile --- 測(cè)試代碼Makefile(這個(gè)也是一個(gè)通用的Makefile)
├── Makefile.log --- 源碼配置Makefile
└── out
這里將日志的相關(guān)文件與頭文件路徑在Makefile.log里封裝好了,該目錄下的Makefile為新增的Makefile,在這個(gè)Makefile里調(diào)用日志源碼的Makefile.log,并添加目標(biāo)文件,這樣使用起來比較簡(jiǎn)單:
include ./Makefile.log #包含源碼文件的makefile
OBJS+=$(LOG_OBJ) #添加目標(biāo)文件
編譯測(cè)試
編譯
執(zhí)行make:
g++ -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c main.cpp -o out/main.o
main.cpp: In function ‘void test_elog()’:
main.cpp:80:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (i = 0; i < sizeof(buf); i++)
^
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/source_code/src/elog_utils.o easylogger/source_code/src/elog_utils.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/source_code/src/elog.o easylogger/source_code/src/elog.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/source_code/src/elog_buf.o easylogger/source_code/src/elog_buf.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/source_code/src/elog_async.o easylogger/source_code/src/elog_async.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/source_code/plugins/file/elog_file.o easylogger/source_code/plugins/file/elog_file.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/easylogger/port/elog_file_port.o easylogger/easylogger/port/elog_file_port.c
gcc -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -c -o easylogger/easylogger/port/elog_port.o easylogger/easylogger/port/elog_port.c
g++ ./out/main.o ./easylogger/source_code/src/elog_utils.o ./easylogger/source_code/src/elog.o ./easylogger/source_code/src/elog_buf.o ./easylogger/source_code/src/elog_async.o ./easylogger/source_code/plugins/file/elog_file.o ./easylogger/easylogger/port/elog_file_port.o ./easylogger/easylogger/port/elog_port.o -o test -I./easylogger/easylogger/inc -I./easylogger/source_code/inc -I./easylogger/source_code/plugins/file -O0 -g3 -Wall -Wall -I. -lpthread
strip test
運(yùn)行
可執(zhí)行文件名稱為test:
日志的輸出效果還是挺好的,對(duì)于數(shù)組可以直接用十六進(jìn)制的形式輸出出來,調(diào)試也很方便。
附錄EasyLogger說明
1. 介紹
EasyLogger?是一款超輕量級(jí)(ROM<1.6K, RAM<0.3K)、高性能的 C/C++ 日志庫,非常適合對(duì)資源敏感的軟件項(xiàng)目,例如:IoT 產(chǎn)品、可穿戴設(shè)備、智能家居等等。相比 log4c、zlog 這些知名的 C/C++ 日志庫, EasyLogger 的功能更加簡(jiǎn)單,提供給用戶的接口更少,但上手會(huì)很快,更多實(shí)用功能支持以插件形式進(jìn)行動(dòng)態(tài)擴(kuò)展。
1.1 主要特性
支持用戶自定義輸出方式(例如:終端、文件、數(shù)據(jù)庫、串口、485、Flash...);
日志內(nèi)容可包含級(jí)別、時(shí)間戳、線程信息、進(jìn)程信息等;
日志輸出被設(shè)計(jì)為線程安全的方式,并支持?異步輸出?及?緩沖輸出?模式;
支持多種操作系統(tǒng)(RT-Thread、UCOS、Linux、Windows...),也支持裸機(jī)平臺(tái);
日志支持?RAW格式?,支持?hexdump?;
支持按?標(biāo)簽?、?級(jí)別?、?關(guān)鍵詞?進(jìn)行動(dòng)態(tài)過濾;
各級(jí)別日志支持不同顏色顯示;
擴(kuò)展性強(qiáng),支持以插件形式擴(kuò)展新功能。
名詞解釋:
1、RAW格式:未經(jīng)過格式化的原始日志。
2、標(biāo)簽:在軟件中可以按照文件、模塊、功能等方面,對(duì)需要打印的日志設(shè)定標(biāo)簽,實(shí)現(xiàn)日志分類。
1.2 插件
1、Flash:使用?EasyFlash?庫提供的Flash操作接口,無需文件系統(tǒng),直接將日志存儲(chǔ)在 Flash 中。
2、File:支持文件轉(zhuǎn)檔、文件循環(huán)保存等與文件日志輸出相關(guān)功能。
3、敬請(qǐng)期待……
1.3 Star & Fork
后續(xù)我還會(huì)提供更多插件。也非常歡迎大家設(shè)計(jì)、開發(fā)更多實(shí)用插件和功能,一起來完善 EasyLogger (Github|OSChina|Coding)?。如果覺得這個(gè)開源項(xiàng)目很贊,可以點(diǎn)擊項(xiàng)目主頁?右上角的?Star?,同時(shí)把它推薦給更多有需要的朋友。
2. 使用
2.1 參數(shù)配置
EasyLogger 擁有過濾方式、輸出格式、輸出開關(guān)這些屬性。
過濾方式支持按照標(biāo)簽、級(jí)別、關(guān)鍵詞進(jìn)行過濾;
可以動(dòng)態(tài)的開啟/關(guān)閉日志的輸出;
可設(shè)定動(dòng)態(tài)和靜態(tài)的輸出級(jí)別
靜態(tài):一級(jí)開關(guān),通過宏定義,在編譯階段使用;
動(dòng)態(tài):二級(jí)開關(guān),通過API接口,在運(yùn)行階段使用。
注:目前參數(shù)配置及輸出方式都是單例模式,即全局只支持一種配置方式。此模式下,軟件會(huì)較為簡(jiǎn)單,但是無法支持復(fù)雜的輸出方式。
2.2 輸出級(jí)別
參考 Android Logcat ,級(jí)別最高為 0(Assert) ,最低為 5(Verbose) 。
0.[A]:斷言(Assert)
1.[E]:錯(cuò)誤(Error)
2.[W]:警告(Warn)
3.[I]:信息(Info)
4.[D]:調(diào)試(Debug)
5.[V]:詳細(xì)(Verbose)
2.2.1 輸出繽紛多彩的日志
各個(gè)級(jí)別日志默認(rèn)顏色效果如下。用戶也可以根據(jù)自己的喜好,在?elog_cfg.h
?對(duì)各個(gè)級(jí)別日志的顏色及字體風(fēng)格進(jìn)行單獨(dú)設(shè)置。
2.3 輸出過濾
支持按照?級(jí)別、標(biāo)簽及關(guān)鍵詞?進(jìn)行過濾。日志內(nèi)容較多時(shí),使用過濾功能可以更快定位日志,保證日志的可讀性。更多的過濾功能設(shè)置方法及細(xì)節(jié)請(qǐng)閱讀docszhapikernel.md
文檔
注:RAW格式、hexdump 格式日志不支持標(biāo)簽、關(guān)鍵詞過濾
2.4 輸出格式
輸出格式支持:級(jí)別、時(shí)間、標(biāo)簽、進(jìn)程信息、線程信息、文件路徑、行號(hào)、方法名。每種優(yōu)先級(jí)別可以獨(dú)立設(shè)置輸出格式。
2.5 輸出方式
通過用戶的移植,可以支持任何一種輸出方式。只不過對(duì)于某種輸出方式可能引入的新功能,需要通過插件實(shí)現(xiàn),例如:文件轉(zhuǎn)存,檢索Flash日志等等。后期會(huì)有更多的插件開源出來。下面簡(jiǎn)單對(duì)比下部分輸出方式使用場(chǎng)景:
終端:方便用戶動(dòng)態(tài)查看,不具有存儲(chǔ)功能;
文件與Flash:都具有存儲(chǔ)功能,用戶可以查看歷史日志。但是文件方式需要文件系統(tǒng)的支持,而Flash方式更加適合應(yīng)用在無文件系統(tǒng)的小型嵌入式設(shè)備中。
2.6 Demo
2.6.1 核心功能
下圖為在終端中輸入命令來控制日志的輸出及過濾器的設(shè)置,更加直觀的展示了 EasyLogger 核心功能。
Demo 路徑:demoosrt-threadstm32f10x
API 文檔:docszhapikernel.md
移植文檔:docszhportkernel.md
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-9Dfqk5E0-1614481257126)(https://raw.githubusercontent.com/armink/EasyLogger/master/docs/zh/images/EasyLoggerDemo.gif)]
2.6.2 Flash Log(將日志保存到 Flash 中)
下圖過程為通過控制臺(tái)輸出日志,并將輸出的日志存儲(chǔ)到 Flash 中。重啟再讀取上次保存的日志,最后清空 Flash 日志。
Demo 路徑:demoosrt-threadstm32f10x
API 文檔:docszhapiflash.md
移植文檔:docszhportflash.md
2.6.2 File Log(將日志保存到文件中)
通過 FIle 插件,可以將日志自動(dòng)保存至文件中。每個(gè)文件可以設(shè)定大小,超過規(guī)定大小后,自動(dòng)新建新的文件來存儲(chǔ)日志。
3. 文檔
具體內(nèi)容參考docszh
下的文件。務(wù)必保證在?閱讀文檔?后再移植使用。
4. 后期
[x] Flash存儲(chǔ):在EasyFlash中增加日志存儲(chǔ)、讀取功能,讓EasyLogger與其無縫對(duì)接。使日志可以更加容易的存儲(chǔ)在?非文件系統(tǒng)中,并具有歷史日志檢索的功能;
[ ] 配置文件:文件系統(tǒng)下的配置文件;
[x] 文件轉(zhuǎn)檔:文件系統(tǒng)下支持文件按容量轉(zhuǎn)檔,按時(shí)間區(qū)分;
[ ] 日志助手:開發(fā)跨平臺(tái)的日志助手,兼容Linux、Windows、Mac系統(tǒng),打開助手即可查看、過濾(支持正則表達(dá)式)、排序、保存日志等。前端:HTML5?+?Bootstrap?+?AngularJS?+?NW.js,后端:Rust?+?iron?+?rust-websocket?+?serial-rs;
[x] 異步輸出:目前日志輸出與用戶代碼之間是同步的方式,這種方式雖然軟件簡(jiǎn)單,也不存在日志覆蓋的問題。但在輸出速度較低的平臺(tái)下,會(huì)由于增加日志功能,而降低軟件運(yùn)行速度。所以后期會(huì)增加?異步輸出?方式,關(guān)鍵字過濾也可以放到異步輸出中去;
[ ] Arduino:增加Arduino lib,并提供其Demo;
5. 許可
MIT Copyright (c) armink.ztl@gmail.com
源碼下載
這個(gè)源碼是我調(diào)整后的:?https://gitee.com/fensnote/EasyLogger.