目前成熟的日誌系統有不少,好比log4cxx,log4cpp等,今天一塊兒來學習log4cxx吧,之因此學習這個,首先,這個日誌庫比較成熟,一直由apach基金在維護,而log4cpp缺少維護.再者,這個庫的性能相對高一些,大約爲10w行/s.c++
log4cxx依賴於apach的另外兩個開源庫apr和apr-util.apache
準備工做:app
首先下載 apr-1.7.0.tar.gz, apr-util-1.6.1.tar.gz和log4cxx庫socket
百度網盤函數
提取碼: kzwc 性能
1. 安裝依賴庫apr和apr-util學習
#首先解壓壓縮包 $ tar -zxvf apr-1.7.0.tar.gz $ cd apr-1.7.0 $ ./configure --prefix=/usr/local $ make $ sudo make install
#首先解壓壓縮包 $ tar -zxvf apr-util-1.6.1.tar.gz $ cd apr-util-1.6.1 $ ./configure --prefix=/usr/local --with-apr=/usr/local $ make $ sudo make install
2.安裝log4cxx測試
tar -zxvf apache-log4cxx-0.10.0.tar.gz cd apache-log4cxx-0.10.0 ./configuer --prefix=/usr/local/ --with-apr=/usr/local/ --with-apr-util=/usr/local/ --with-charset=utf-8 --with-logchar=utf-8 make sudo make install
安裝log4cxx可能會報錯:ui
解決辦法:this
1 inputstreamreader.cpp:66: error: 'memmove' was not declared in this scope 2 make[3]: *** [inputstreamreader.lo] 錯誤 1 #這是因爲如下幾個文件缺乏了標準庫文件,添加上就能夠了 3 src/main/cpp/inputstreamreader.cpp添加#include <string.h> 4 src/main/cpp/socketoutputstream.cpp添加#include <string.h> 5 src/examples/cpp/console.cpp添加#include <string.h>;#include <stdio.h>;
3. 封裝log4cxx日誌庫
/*! * Email: scictor@gmail.com * Auth: scictor * Date: 2019-9-8 * File: zlog4cxx.h * Class: zlog4cxx (if applicable) * Brief: * Note: */ #ifndef ZLOG4CXX_H #define ZLOG4CXX_H #include <log4cxx/logger.h> #include <log4cxx/logstring.h> #include <log4cxx/propertyconfigurator.h> #include<string> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace log4cxx; using namespace log4cxx::helpers; #include <stdarg.h> using namespace std; #define SAFE_DELETE_ARRAY(v_para)\ do \ {\ if (NULL != v_para) {\ delete[] v_para;\ v_para = NULL;\ }\ } while (0) //TRACE < DEBUG < INFO < WARN < ERROR < FATAL typedef enum _LOG_LEVEL { LOG_TRACE_ = 0, LOG_DEBUG_, LOG_INFO_, LOG_WARN_, LOG_ERROR_, LOG_FATAL_ }LOG_LEVEL; #ifndef IN #define IN #endif #ifndef OUT #define OUT #endif /* 寫日誌函數 IN const char* module,//在log4cxx.properties文件中設置了不少個append,這個參數用來設置模塊,例如本實例中的fa IN const LOG_LEVEL level,日誌級別 ERROR、INFO等 IN const char* file,打印日誌函數調用的文件 IN const char* function, 打印日誌的函數 IN const int line, 打印日誌的行號 IN const char* format,//打印日誌的格式 如: "%s%d%f" ... //可變參數輸入 */ void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function, IN const int line, IN const char* format, ...);// //宏定義封裝,__FILE__, __FUNCTION__, __LINE__ 分別是打印日誌的文件名、函數名,行號 #define LOG(module,level, format,...) log4cxx_package(module,level, __FILE__, __FUNCTION__, __LINE__, format,__VA_ARGS__) //按照不一樣的級別定義宏 #define FIRE_ERROR(format,...) LOG("fa",LOG_ERROR_, format,__VA_ARGS__) #define FIRE_INFO(format,...) LOG("fa",LOG_INFO_, format,__VA_ARGS__) #define FIRE_TRACE(format,...) LOG("fa",LOG_TRACE_, format,__VA_ARGS__) #define FIRE_DEBUG(format,...) LOG("fa",LOG_DEBUG_, format,__VA_ARGS__) #define FIRE_WARN(format,...) LOG("fa",LOG_WARN_, format,__VA_ARGS__) #define FIRE_FATAL(format,...) LOG("fa",LOG_FATAL_, format,__VA_ARGS__) // //初始化日誌庫,傳入log4cxx.properties文件的名稱 void log4cxx_init(IN const char* conffile); //根據append或者模塊名稱來獲取模塊的日誌指針。若是是root模塊,直接用Logger::getRootLogger();獲取 LoggerPtr get_logger_ptr(IN const char* user); #endif // ZLOG4CXX_H
源文件
/*! * Email: scictor@gmail.com * Auth: scictor * Date: 2019-9-8 * File: zlog4cxx.cpp * Class: zlog4cxx (if applicable) * Brief: * Note: */ #include "zlog4cxx.h" static std::string ensure_log_complete(IN const char* format,IN va_list args) { if (NULL == format) { return ""; } int iNum = 0; unsigned int uiSize = 1024; string strLog(""); char *pcBuff = new(std::nothrow) char[uiSize]; if (NULL == pcBuff) { return strLog; } while(true) { memset(pcBuff, 0,uiSize); iNum = vsnprintf(pcBuff, uiSize, format, args); if ((iNum > -1) && (iNum < (int)uiSize)) { strLog = pcBuff; SAFE_DELETE_ARRAY(pcBuff); return strLog; } //若是字符串值比默認分配大,則分配更大空間 uiSize = (iNum > -1)?(int)(iNum + 1):(uiSize * 2); SAFE_DELETE_ARRAY(pcBuff); pcBuff = new(std::nothrow) char[uiSize]; if (NULL == pcBuff) { return strLog; } } SAFE_DELETE_ARRAY(pcBuff); return strLog; } /* 寫日誌函數 IN const char* module,//在log4cxx.properties文件中設置了不少個append,這個參數用來設置模塊,例如本實例中的fa IN const LOG_LEVEL level,日誌級別 ERROR、INFO等 IN const char* file,打印日誌函數調用的文件 IN const char* function, 打印日誌的函數 IN const int line, 打印日誌的行號 IN const char* format,//打印日誌的格式 如: "%s%d%f" ... //可變參數輸入 */ void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function, IN const int line, IN const char* format, ...) { if (level > LOG_FATAL_ || level < LOG_TRACE_) { return; } if (NULL == file || NULL == function || NULL == format) { return; } LoggerPtr pLogger=nullptr; if (module!=NULL) { pLogger=get_logger_ptr(module); } if(pLogger==NULL) { pLogger= Logger::getRootLogger(); } char acTmp[30] = { 0 }; sprintf(acTmp,"%d",line); va_list args; std::string strLog; strLog = "[" + std::string(file) + ":" + std::string(function) + "(" + std::string(acTmp) + ")] "; va_start(args, format); strLog += ensure_log_complete(format, args); va_end(args); switch (level) { case LOG_TRACE_: LOG4CXX_TRACE(pLogger, strLog.c_str()); break; case LOG_DEBUG_: LOG4CXX_DEBUG(pLogger, strLog.c_str()); break; case LOG_INFO_: LOG4CXX_INFO(pLogger, strLog.c_str()); break; case LOG_WARN_: LOG4CXX_WARN(pLogger, strLog.c_str()); break; case LOG_ERROR_: LOG4CXX_ERROR(pLogger, strLog.c_str()); break; case LOG_FATAL_: LOG4CXX_FATAL(pLogger, strLog.c_str()); break; default: break; } return; } void log4cxx_init(IN const char* conffile)//初始化日誌庫 { // 讀取配置文件 using namespace log4cxx; PropertyConfigurator::configure(File(conffile)); return ; } LoggerPtr get_logger_ptr(IN const char* user)//獲取日誌模塊指針 { // 創建logger return Logger::getLogger(user); }
4. 測試
/*! * Email: scictor@gmail.com * Auth: scictor * Date: 2019-9-8 * File: %{Cpp:License:FileName} * Class: %{Cpp:License:ClassName} (if applicable) * Brief: * Note: */ #include <bits/stdc++.h> #include "zlog4cxx.h" using namespace std; int main(int argc,char **argv){ log4cxx_init("log4cxx.properties"); char *pStr = "YES"; FIRE_INFO("that is ok? %s", pStr); printf("hello world!\n"); return 0; }
編譯:
g++11 zlog4cxx.cpp main.cpp -o xlog -llog4cxx
結果輸出