1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > c++ 可变参数 log 打印函数实现

c++ 可变参数 log 打印函数实现

时间:2019-09-01 22:26:40

相关推荐

c++ 可变参数 log 打印函数实现

背景

项目需求:

要打印日志到特定模块、特定文件,并打印相应时间戳到文件中。日志开关,可以通过开关关闭、打开。代码可以通过开关关闭、打开。(代码直接不进行编译)

需求分析:

日志打印涉及可变参数,涉及log 等级,打印到模块-文件可以通过fstream实现。日志开关,通过宏开关实现。代码编译开关,也可以通过宏实现。

代码实现

log_test.h

#ifndef LOG_TEST_H_#define LOG_TEST_H_#include <string>#include <fstream>namespace my_log_test {//log switch#define MY_LOG_DEBUG 1//log write to output console#define MY_LOG_OUTPUT_CONSOLE 1//log buffer size#define MY_LOG_BUFFER_SIZE 512constexpr const char* g_testDirPath { "./testDir/" };typedef enum {LOG_FATAL = 0,LOG_ERROR = 1,LOG_WARN = 2,LOG_INFO = 3,LOG_UNKNOW} MY_LOG_LEVEL;class MyLogTest {public:MyLogTest(std::string fileName, std::string moduleName = "");~MyLogTest();static void LogPrint(MY_LOG_LEVEL level, const char* pcFunc, const int& line, const char* fmt, ...);private:std::ofstream writeOf;bool fsOpenFlag {false};}; //end of class MyLogTest//日志打印函数,可变参数。可通过宏开关,整个代码不编译#ifdef MY_LOG_DEBUG#ifndef MY_LOGERR#define MY_LOGERR(fmt, args...) MyLogTest::LogPrint(LOG_ERROR, __FUNCTION__, __LINE__, fmt, ## args)#endif#else#define MY_LOGERR(fmt, args...) ((void)0)#endif//日志打印函数,可变参数。可通过宏开关,整个代码不编译#ifdef MY_LOG_DEBUG#ifndef MY_LOGWAR#define MY_LOGWAR(fmt, args...) MyLogTest::LogPrint(LOG_WARN, __FUNCTION__, __LINE__, fmt, ## args)#endif#else#define MY_LOGWAR(fmt, args...) ((void)0)#endif//类使用宏,可通过宏开关,整个代码不编译#ifdef MY_LOG_DEBUG#ifndef DefineMyLogTest#define DefineMyLogTest(fileName, moduleName) \MyLogTest myLogTest(fileName, moduleName)#endif#else#define DefineMyLogTest(fileName, moduleName) ((void)0)#endif}//end of namespace my_log_test#endif //LOG_TEST_H_

log_test.cpp

#include <iostream>#include <fstream>//获取系统时间,可变参数#include <stdlib.h>#include <time.h>#include <stdarg.h>#include "log_test.h"namespace my_log_test {void * BaseMyLogTest { nullptr };//获取当前系统时间void gettime(std::string *date_time){time_t rawtime;struct tm *ptminfo;char buf[32];time(&rawtime);ptminfo = localtime(&rawtime);strftime(buf, 32, "%Y-%m-%d %H:%M:%S", ptminfo);*date_time = buf;//std::cout<<"date-time: " <<buf<<std::endl;}MyLogTest::MyLogTest(std::string fileName, std::string moduleName){if( fileName.empty()) {std::string file {__FILE__};if(file.find(".cpp")) {fileName = file.substr(0, file.size()-5);}}if(!moduleName.empty()) {fileName = moduleName + "-" + fileName;}BaseMyLogTest = (void*)this;fileName = g_testDirPath + fileName;writeOf.open(fileName, std::ios::out);if(writeOf.fail()) {std::cout<<__FUNCTION__<<" open file failed: "<< fileName <<std::endl;fsOpenFlag = false; }else {fsOpenFlag = true;}if(fsOpenFlag) {std::string date_time {""};gettime(&date_time);std::cout<<__FUNCTION__<<" "<<date_time << std::endl;writeOf <<"My log test Begin date-time: "<<date_time<<std::endl;}}MyLogTest::~MyLogTest(){if(fsOpenFlag) {writeOf.close();}}void MyLogTest::LogPrint(MY_LOG_LEVEL level, const char*pcFunc, const int& line, const char* fmt, ...){char buffer[MY_LOG_BUFFER_SIZE];int n = sprintf(buffer, "[%s]-[%d]", pcFunc, line);va_list vap;va_start(vap, fmt);vsnprintf(buffer + n, MY_LOG_BUFFER_SIZE-n, fmt, vap);va_end(vap);std::string logLevelStr {""};switch(level) {case LOG_ERROR:logLevelStr = "Error";break;case LOG_WARN:logLevelStr = "Warn";break;default:logLevelStr = "Error";break;}std::string dt {""};gettime(&dt);#ifdef MY_LOG_OUTPUT_CONSOLEstd::cout<<dt <<" [" <<logLevelStr << "]: " <<buffer << std::endl;#elseMyLogTest *myLogTest = (MyLogTest*)BaseMyLogTest ;myLogTest->writeOf <<dt <<" [" <<logLevelStr << "]: " <<buffer << std::endl;#endif}}//end of namespace my_log_test

main.cpp

#include <iostream>#include "log_test.h"using namespace my_log_test;int main(int argc, char* argv[]){std::cout<< __FUNCTION__ <<" Begin of the program!"<< std::endl;DefineMyLogTest("test_file", "test_module");std::string strErr {"string error!"};std::string strWar {"string waring!"};MY_LOGERR("my log test error: %s", strErr.c_str());MY_LOGWAR("my log test warn: %s", strWar.c_str();std::cout<< __FUNCTION__ <<" End of the program!"<< std::endl;return 0;}

代码测试

当前代码在 ubuntu 系统上运行,通过下面命令进行编译。

g++ -std=c++11 log_test.cpp main.cpp -o test

在当前目录创建 ”testDir“ 文件夹,执行 ./test

即会在终端打印部分日志,并在文件 ./testDir/test_module_test_file 中写入日志,及时间戳。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
C++ 可变参数

C++ 可变参数

2023-09-01

C++可变参数函数

C++可变参数函数

2019-01-21

C++可变参数

C++可变参数

2023-09-18

C++ 可变参数模板

C++ 可变参数模板

2018-07-25