概述
在現(xiàn)代軟件開發(fā)中,日志記錄系統(tǒng)是不可或缺的一部分。它不僅可以幫助開發(fā)人員在應(yīng)用程序中定位和解決問題,還可以用于監(jiān)控、性能分析、安全審計(jì)等方面。本文將介紹日志記錄系統(tǒng)的基本概念、重要性以及如何構(gòu)建一個(gè)高效的日志記錄系統(tǒng)。
為什么需要日志記錄系統(tǒng)?
日志是應(yīng)用程序在運(yùn)行時(shí)生成的文本消息,用于記錄關(guān)鍵事件、錯(cuò)誤信息、警告以及其他有價(jià)值的信息。日志記錄系統(tǒng)的作用如下:
故障排除與問題定位:當(dāng)應(yīng)用程序出現(xiàn)問題時(shí),日志可以提供關(guān)于發(fā)生了什么、在哪里發(fā)生以及為什么發(fā)生的關(guān)鍵信息,幫助開發(fā)人員快速定位和解決問題。
性能分析:通過記錄關(guān)鍵操作的時(shí)間戳和執(zhí)行時(shí)間,開發(fā)人員可以分析應(yīng)用程序的性能瓶頸,并進(jìn)行優(yōu)化。
監(jiān)控與報(bào)警:監(jiān)控系統(tǒng)可以分析日志,實(shí)時(shí)監(jiān)控應(yīng)用程序的健康狀態(tài)。當(dāng)出現(xiàn)異常情況時(shí),可以觸發(fā)報(bào)警機(jī)制,使團(tuán)隊(duì)可以及時(shí)采取措施。
安全審計(jì):記錄安全相關(guān)事件和訪問,以便進(jìn)行后續(xù)的審計(jì)和分析。
構(gòu)建日志記錄系統(tǒng)的關(guān)鍵步驟
日志級(jí)別與分類:日志級(jí)別包括調(diào)試(Debug)、信息(Info)、警告(Warning)、錯(cuò)誤(Error)等。不同級(jí)別的日志用于不同目的,例如調(diào)試時(shí)使用調(diào)試日志來追蹤代碼執(zhí)行,而錯(cuò)誤日志用于記錄嚴(yán)重的問題。選擇合適的日志級(jí)別可以避免日志信息過于冗雜或過于稀少。
日志格式與結(jié)構(gòu):一個(gè)良好的日志格式應(yīng)包括時(shí)間戳、日志級(jí)別、模塊/組件名以及具體的日志消息。統(tǒng)一的格式使得日志易于閱讀和分析。例如:[時(shí)間戳] [日志級(jí)別] [模塊名] - 日志消息
異步日志寫入:為避免阻塞應(yīng)用程序的正常執(zhí)行,可以采用異步日志寫入方式。日志消息被緩沖并在適當(dāng)?shù)臅r(shí)機(jī)寫入磁盤,從而提高應(yīng)用程序的性能。
日志存儲(chǔ)與滾動(dòng):考慮使用滾動(dòng)策略,定期歸檔或刪除舊的日志文件,以免日志文件無(wú)限增大。選擇適當(dāng)?shù)拇鎯?chǔ)方式,如本地文件、數(shù)據(jù)庫(kù)或云存儲(chǔ)。
上下文信息:除了基本的日志信息外,還可以在日志中添加上下文信息,如用戶ID、請(qǐng)求ID、會(huì)話ID等。這些信息有助于在復(fù)雜的分布式系統(tǒng)中跟蹤請(qǐng)求流程。
敏感信息與安全:避免將敏感信息(如密碼、API密鑰)寫入日志。同時(shí),實(shí)施權(quán)限控制,限制對(duì)日志文件的訪問,確保敏感信息不被濫用。
日志分析與可視化:利用日志分析工具或平臺(tái),對(duì)日志進(jìn)行聚合、搜索和可視化分析。這有助于發(fā)現(xiàn)模式、趨勢(shì)以及潛在問題。
Rlog組件
Rlog作為一款高性能的純C語(yǔ)言日志組件,為開發(fā)人員提供了一種輕松、靈活且可定制的日志記錄解決方案。其簡(jiǎn)單的接口和插件擴(kuò)展功能使得它適用于各種不同規(guī)模和類型的項(xiàng)目。無(wú)論是小型應(yīng)用程序還是大型系統(tǒng),Rlog都能為您提供高效的日志記錄支持,幫助您更好地理解和管理應(yīng)用程序的運(yùn)行狀態(tài)。
純C語(yǔ)言開發(fā):Rlog完全由C語(yǔ)言編寫,因此具有廣泛的可移植性和兼容性。它可以輕松地集成到各種C語(yǔ)言項(xiàng)目中。
簡(jiǎn)單的接口:Rlog提供了簡(jiǎn)單、直觀的接口,使開發(fā)人員可以輕松地在代碼中插入日志記錄語(yǔ)句。這使得調(diào)試和問題定位變得更加容易。
靈活可配置:Rlog允許開發(fā)人員根據(jù)項(xiàng)目需求進(jìn)行高度自定義的配置。您可以定義日志級(jí)別、格式、輸出位置等,以滿足不同應(yīng)用場(chǎng)景的需求。
插件擴(kuò)展:一個(gè)突出的特點(diǎn)是Rlog的插件式擴(kuò)展輸出端點(diǎn)的能力。這意味著您可以將日志消息輸出到各種不同的地方,如文件、終端、遠(yuǎn)程服務(wù)器等,以適應(yīng)多樣化的需求。
Rlog特性
支持用戶自定義輸出端點(diǎn)(例如:串口終端、網(wǎng)絡(luò)中斷、Flash...),輸出端點(diǎn)以插件形式自定義擴(kuò)展。
日志內(nèi)容可包含日志等級(jí)、時(shí)間戳、行號(hào),函數(shù)信息,文件信息;
支持多種操作系統(tǒng)(RT-Thread、Linux...),也支持裸機(jī)平臺(tái);
日志輸出支持:printf原始格式,日志等級(jí)輸出,hexdump輸出;
Rlog目錄結(jié)構(gòu)
?
. ├──?example │???├──?rlog_linux_adapter.c????????/*?linux環(huán)境下的適配接口?*/ │???└──?rlog_rtt_adapter.c??????????/*?rt-thread環(huán)境下的適配接口?*/ ├──?include/ │???├──?rlog_adapter.h??????????????/*?rlog適配描述?*/ │???└──?rlog.h??????????????????????/*?rlog對(duì)外接口?*/ ├──?main.c??????????????????????????/*?rlog的測(cè)試樣例?*/ ├──?Makefile????????????????????????/*?linux環(huán)境rlog構(gòu)建Makefile?*/ ├──?plug-in?????????????????????????/*?輸出端點(diǎn)插件的存放路徑?*/ ├──?SConscript??????????????????????/*?rt-thread環(huán)境rlog構(gòu)建腳本?*/ └──?src ????├──?rlog.c??????????????????????/*?rlog核心代碼?*/ ????├──?rlog_def.h??????????????????/*?rlog核心代碼使用的定義?*/ ????└──?rlog_utils.c????????????????/*?rlog使用的C庫(kù)接口?*/
?
Rlog靈活配置
靜態(tài)配置:
靜態(tài)配置采用宏定義的方式,用戶可直接修改rlog_adapter.h頭文件的宏定義,就可以修正相關(guān)配置;
靜態(tài)配置的管控權(quán)限比動(dòng)態(tài)配置的高,例如:靜態(tài)配置設(shè)置日志輸出總開關(guān)為關(guān)閉,動(dòng)態(tài)配置設(shè)置日志輸出使能,日志已經(jīng)無(wú)法輸出。
配置描述如下:
?
/*?Enable?log?output?*/ #define?RLOG_OUTPUT_ENABLE??????????????1 /*?Set?log?output?level,?rang:?from?RLOG_LEVEL_ASSERT?to?RLOG_LEVEL_VERBOSE?*/ #define?RLOG_OUTPUT_LEVEL???????????????RLOG_LEVEL_VERBOSE /*?Enable?log?color?*/ #define?RLOG_COLOUR_ENABLE??????????????1 /*?Enable?log?color?*/ #define?RLOG_TIME_ENABLE????????????????1 /*?Support?log?include?directory?*/ #define?RLOG_DIRECTORY_ENABLE???????????1 /*?Support?log?include?funtiong?name?*/ #define?RLOG_FUNCTION_ENABLE????????????1 /*?Support?log?include?line?number*/ #define?RLOG_LINE_ENABLE????????????????1 /*?Buffer?size?for?every?line's?log?*/ #define?RLOG_LINE_BUFF_LEN??????????????128 /*?Output?line?number?max?length?*/ #define?RLOG_LINE_NUM_SIZE??????????????5 /*?Output?newline?sign?*/ #define?RLOG_NEWLINE_SIGN???????????????" " /*?Enable?assert?check?*/ #define?RLOG_ASSERT_ENABLE??????????????1 /*?Log?function.?default?FDB_PRINT?macro?is?printf()?*/ #define?RLOG_PRINT(...)?????????????????printf(__VA_ARGS__)
?
?
?
宏 | 描述 |
---|---|
RLOG_OUTPUT_ENABLE | rlog日志輸出總開關(guān) |
RLOG_OUTPUT_LEVEL | rlog日志輸出等級(jí)總開關(guān) |
RLOG_COLOUR_ENABLE | rlog日志等級(jí)輸出帶顏色開關(guān) |
RLOG_TIME_ENABLE | rlog日志等級(jí)輸出帶時(shí)間開關(guān) |
RLOG_DIRECTORY_ENABLE | rlog日志等級(jí)輸出帶文件路徑開關(guān) |
RLOG_FUNCTION_ENABLE | rlog日志等級(jí)輸出帶函數(shù)名開關(guān) |
RLOG_LINE_ENABLE | rlog日志等級(jí)輸出帶行號(hào)開關(guān) |
RLOG_LINE_BUFF_LEN | rlog每一條日志最大長(zhǎng)度 |
RLOG_LINE_NUM_SIZE | rlog日志等級(jí)輸出行號(hào)的最大長(zhǎng)度 |
RLOG_NEWLINE_SIGN | rlog日志換行符格式 |
RLOG_ASSERT_ENABLE | rlog使用assert功能 |
RLOG_PRINT(...) | rlog中斷輸出設(shè)置,如rt-thread采用rt_kprintf, linux采用printf |
?
動(dòng)態(tài)配置:
動(dòng)態(tài)配置采用接口的方式,用戶通過調(diào)用rlog.h頭文件提供的接口設(shè)置;
動(dòng)態(tài)配置的管控權(quán)限比靜態(tài)配置的低,例如:靜態(tài)配置設(shè)置日志輸出總開關(guān)為關(guān)閉,動(dòng)態(tài)配置設(shè)置日志輸出使能,日志已經(jīng)無(wú)法輸出。
?
/** ?*?RLog?output?enable ?*? ?*?@param?enable?true:?enable?output,?false:?disable?output? ?*/ void?rlog_enable(bool?enable); /** ?*?RLog?output?color?enable ?*? ?*?@param?enable?true:?enable?output?color,?false:?disable?output?color ?*/ void?rlog_color_enable(bool?enable); /** ?*?RLog?level?output?format?setting ?*? ?*?@param?level??log?level ?*?@param?format?log?format ?*/ void?rlog_level_fmt_set(rlog_lvl_t?level,?int?format); /** ?*?RLog?level?output?format?setting ?*? ?*?@param?level??log?level ?*?@param?format?log?format ?*? ?*?@return?result?true:?supported?format,?false:?unsupported?format ?*/ bool?rlog_level_fmt_get(rlog_lvl_t?level,?int?format); /** ?*?RLog?filter?the?content?of?the?log?level ?*? ?*?@param?level??log?level ?*/ void?rlog_level_filter_set(rlog_lvl_t?level);
配置函數(shù) | 描述 |
---|---|
rlog_enable | rlog日志輸出使能開關(guān) |
rlog_color_enable | rlog日志等級(jí)輸出帶顏色開關(guān) |
rlog_level_fmt_set | rlog日志等級(jí)輸出格式設(shè)置,RLOG_FMT_LVL/RLOG_FMT_TAG/RLOG_FMT_TIME/RLOG_FMT_DIR/RLOG_FMT_FUNC/RLOG_FMT_LINE |
rlog_level_fmt_get | rlog日志等級(jí)輸出格式獲取 |
rlog_level_filter_set | rlog日志等級(jí)輸出過濾設(shè)置 |
?
Rlog適配
不同平臺(tái)的適配方式不同,所以為rlog核心層提供了統(tǒng)一的接口,適配接口如下:
?
void?rlog_adapter_init(void); void?rlog_adapter_deinit(void); void?rlog_lock(void); void?rlog_unlock(void); char?*rlog_get_time(void); void?rlog_output(const?char?*log,?uint16_t?len);
適配函數(shù) | 描述 |
---|---|
rlog_adapter_init | rlog適配層初始化,如端點(diǎn)插件初始化 |
rlog_adapter_deinit | rlog適配層去初始化,如端點(diǎn)插件去初始化 |
rlog_lock | rlog日志鎖,為rlog提供線程安全 |
rlog_unlock | rlog日志解鎖,為rlog提供線程安全 |
rlog_get_time | rlog日志提供時(shí)間 |
rlog_output | rlog日志輸出適配接口 |
?
linux下的適配方式:
?
static?pthread_mutex_t?mutex; void?rlog_lock(void) { ????pthread_mutex_lock(&mutex); } void?rlog_unlock(void) { ????pthread_mutex_unlock(&mutex); } char?*rlog_get_time(void) { #define?TIME_STR_SIZE???????32 ????static?char?time_str[TIME_STR_SIZE]?=?{0}; ????time_t?tmp; ????struct?tm?*timp; ????time(&tmp);??? ????timp?=?localtime(&tmp); ????memset(time_str,?0,?TIME_STR_SIZE); ????rlog_snprintf(time_str,?TIME_STR_SIZE,?"%04d-%02d-%02d?%02d:%02d:%02d",? ????????????????????????????????(1900?+?timp->tm_year),?(1?+?timp->tm_mon),?timp->tm_mday, ????????????????????????????????timp->tm_hour,?timp->tm_min,?timp->tm_sec); ????return?time_str; } void?rlog_output(const?char?*log,?uint16_t?len) { ????RLOG_PRINT("%.*s",?len,?log); } void?rlog_adapter_init(void) { ????pthread_mutex_init(&mutex,?NULL); } void?rlog_adapter_deinit(void) { ????pthread_mutex_destroy(&mutex); }
?
Rlog驗(yàn)證
rlog驗(yàn)證以linux環(huán)境為例,Rlog開源路徑:https://gitee.com/RiceChen0/rlog
rlog驗(yàn)證操作流程:
?
youyeetoo@youyeetoo:~$?git?clone?https://gitee.com/RiceChen0/rlog.git youyeetoo@youyeetoo:~/rlog$?make youyeetoo@youyeetoo:~/rlog$?./output/rlog_1.0.0? RLog?Version:?v1.0.0 RLog?Author:?RiceChen RLog?Contact:?https://gitee.com/RiceChen0/rlog Youyeetoo (2023-08-15?18:53:27)[main.c?main:12]I/RLOG:?Youyeetoo RLOG?HexDump--Title:?RLOG,?len:?9 00000000:?59?6F?75?79?65?65?74?6F?6F???????????????????????Youyeetoo
?
rlog驗(yàn)證效果:
Rlog總結(jié)
rlog提供了簡(jiǎn)單易用的日志系統(tǒng),采用插件方式,提供靈活的輸出端點(diǎn)的設(shè)置。
rlog的原型參考了開源項(xiàng)目:https://gitee.com/RT-Thread-Mirror/EasyLogger。
rlog不依賴C庫(kù),rlog_utils.c中,重新定義了C庫(kù)接口。
下一步計(jì)劃:
rlog提供不同場(chǎng)景下的插件,網(wǎng)絡(luò)中斷,文件存儲(chǔ),異步操作。
rlog將提供對(duì)應(yīng)的上位機(jī),上位機(jī)功能將集成到RTOOLS中。
編輯:黃飛
?
評(píng)論
查看更多