本文主要是介绍C++ Log4cpp跨平台日志库的使用小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下...
项目中,最重要的模块之一就是日志了,今天这篇博客记录项目中log4cpp的用法!
Log4cpp是c++类库,用于灵活地记录文件、syslog、IDSA和其他目的地。它是在Log4j Java库之后建模的,尽可能地接近它们的API。
一、介绍
1. log4cpp的日志方式
log4cpp::FileAppender // 输出到文件(常用)
log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷(常用)
log4cpp::OstreamAppender // 输出到一个ostream类(常用)
log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
log4cpp::StringQueueAppender // 内存队列
log4cpp::SyslogAppender // 本地syslog
log4cpp::Win32DebugAppender // 发送到缺省系统调试器
log4cpp::NTEventLogAppender // 发送到win 事件日志
2.设置日志输出的格式
log4cpp::FileAppender* appender = new log4cpp::FileAppender("appender", "text.log");
例如:
PatternLayout:自定义日志格式
log4cpp::PatternLayout *patternLayout = new log4cpp::PatternLayout(); patternLayout->setConversionPattern("%d [%p] - %m%n"); appender->setLayout(patternLayout);
PatternLayout支持以下一组格式字符:
- %% - 一个百分号;
- %c - the category;
- %d - date日期格式:日期格式字符后面可以跟着花括号括起来的日期格式说明符。例如,%d China编程 {% H: % M: % S、l %}或% d {% d % M H % Y %: % M: % S、l %}。如果没有给出日期 格式说明符,则使用以下格式:"Wed Jan 02 02:03:55 1980"。日期格式说明符承认与 ANSI C函数strftime相同的语法,只是增加了1个。加号是以毫秒为单位的说明符%l,用 0填充为3位数字;
- %m - 你要输出的日志信息;
- %n - 换行符;
- %p - 优先级;
- %r - 该布局创建后的毫秒数;
- %R - 从1970年1月1日0时开始到目前为止的秒数;
- %u - 进程开始到目前为止的时钟周期数;
- %x - the NDC;
- %t - 线程的名字;
- 默认情况下,PatternLayout的ConversionPattern设置为“%m%n”。
3. 设置日志的输出优先级
log4cpp::Category &root = log4cpp::Category::getRoot(); root.setPriority(log4cpp::Priority::NOTICE); root.addAppender(appender);
日志的级别总共有:
NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG
日志级别的意思是低于该级别的日志不会被记录。
二、Window
1. 下载log4cpp
log4cpp官网:
Log for C++ Project
下载后解压进入msvc10
因为官方提供的是vs2010编译的项目,所以根据自己电脑装的vs去打开即可,例如我这里使用vs2017去打开,打开后会提示升级,升级即可。
2. 编译
3. 报错解决1
不出意外的话,会报错。
解决方法:①在log4cpp项目工程中找到NTEventLogCategories.mc文件,选择该文件上然后右键选择属性,在弹出窗口中找到“配置属性 - 自定义生成工具 - 常规 - 命令行”中修改编译命令,设置为如下命令:
if not exist $(OutDir) md $(OutDir) mc.exe -h $(OutDir) -r $(OutDir) $(ProjectDir)..\%(Filename).mc RC.exe -r -fo $(OutDir)%(Filename).res $(OutDir)%(Filename).rc link.exe /MACHINE:IX86 -dll -noentry -out:$(OutDir)NTEventLogAppender.dll $(OutDir)%(Filename).res
然后再次右键log4cpp,选择重新编译!
不出意外的话,再次报错。
4. 报错解决2
解决方法:由于log4cpp中对snprintf进行了重新实现,visual studio的c库对snprintf也有实现,Windows中在链接时会报snprintf函数冲突,所以需要设置log4cpp的预编译项,选择使用visual stuido中c库的实现,在log4cpp工程上点右键选属性,在”配置属性 - C/C++ - 预处理器 - 预处理器定义"中增加一条预处理定义 。
HAVE_SNPRINTF
再次编译!
5. 编译成功
不出意外的话,编译通过!
进入路径log4cpp-1.1.3\log4cpp\msvc10\log4cpp\Debug,编译好的库就在这里。
头文件路径:log4cpp-1.1.3\log4cpp
注意,这是编译x86(Win32)的库,如果需要编译x64的库,在项目中添加x64的库后进行编译即可;编译好的库路径:log4cpp-1.1.3\log4cpp\msvc10\x64\Debug
Release库编译方式与上面方式一样!
6. 测试
官方例子,稍作修改
新建项目,将上面编译好的 log4cpp.dll 和 log4cpp.lib 和 /include 文件夹拷贝到项目路径中去
#include "log4cpp/Category.hh" #include "log4cpp/Appender.hh" #include "log4cpp/FileAppender.hh" #include "log4cpp/OstreamAppender.hh" #include "log4cpp/Layout.hh" #include "log4cpp/BasicLayout.hh" #include "log4cpp/Priority.hh" #include "log4cpp/PatternLayout.hh" int main(void) { /* 1.日志输出到控制台 */ { log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout); appender1->setLayout(new log4cpp::BasicLayout()); // 默认配置 log4cpp::Category& root = log4cpp::Category::getRoot(); root.setPriority(log4cpp::Priority::WARN); root.addAppender(appender1); // 1.use of functions for logging messages root.debug("root debug"); root.warn("root warn"); root.error("root error"); root.info("root info"); // 2.printf-style for logging variables root.warn("%d + %d == %s ?", 1, 1, "two"); // 3.use of streams for logging messages root << log4cpp::Priority::ERROR << "Streamed root error"; root << log4cpp::Priority::INFO << "Streamed root info"; // 4.or this way: root.errorStream() << "Another streamed error"; root.debugStream() << "Another streamed debug"; } /* 2.日志输出到控制台和本地文件 */ { log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log"); appender2->setLayout(new log4cpp::BasicLayout()); log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1")); sub1.addAppender(appender2); sub1.error("sub1 error"); sub1.warn("sub1 warn"); sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error"; sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn"; } /* 3.日志输出到本地文件 */ { std::string logFileName = "test.log"; // 优先级 log4cpp::Priority::PriorityLevel logPri = log4cpp::Priority::DEBUG; // 自定义布局 log4cpp::PatternLayout* logLayout = new log4cpp::PatternLayout(); logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] : %m%n"); // 日志输出到本地文件 log4cpp::FileAppender* logFile = new log4cpp::FileAppender("default", logFileName); logFile->setLayout(logLayout); // 设置自定义布局 // 输出日志的操作类 log4cpp::Category& logCat = log4cpp::Category::getInstance("logCat"); logCat.addAppender(logFile); 编程China编程//设置优先级 logCat.setPriority(logPri); logCat.error("测试 error"); logCat.debug("测试 debug"); logCat.warn("%d + %d == %s ?", 1, 1, "two"); logCat << log4cpp::Priority::ERROR << "Streamed root error"; logCat << log4cpp::Priority::INFO << "Streamed root info"; logCat.errorStream() << "Another streamed error"; logCat.debugStream() << "Another streamed debug"; } // 关闭日志 log4cpp::Category::shutdown(); return 0; }
三、Linux
1. 下载Log4cpp
可以通过上面的官网去下载,然后再拷入Linux系统中!
或者根据自己系统的特性,使用下面链接去下载,
https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28new%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz
例如Ubuntu:wget https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28new%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz
下载后,使用命令tar -zxvf log4cpp*.tar.gz 去解压。
2. 编译安装
然后 cd log4cpp* 进入文件夹
然后执行 ./configure
然后执行 make
然后执行 make install
即可安装成功!
命令汇总:
wget https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28new%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz tar xzvf log4cpp-1.1.3.tar.gz cd log4cpp-1.1.3 ./configure make make install
安装完毕后,log4cpp库路径在 /usr/local/lib
可以使用命令 mv -if /usr/local/lib/liblog4cpp.* 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个lib文件夹,将刚刚安装的log4cpp库拷贝到此文件夹中
log4cpp头文件路径在 /usr/local/include/log4cpp
可以使用命令 mv -if /usr/local/include/log4cpp 自己的项目路径 拷贝到自己的项目路径中去;例如,我会在项目路径中创建一个include文件夹,将刚刚安装的log4cpp头文件拷贝到此文件夹中
3. 测试
#include "log4cpp/Category.hh" #include "log4cpp/Appender.hh" #include "log4cpp/FileAppender.hh" #include "log4cpp/OstreamAppender.hh" #javascriptinclude "log4cpp/Layout.hh" #include "log4cpp/BasicLayout.hh" #include "log4cpp/Priority.hh" #include "log4cpp/PatternLayout.hh" int main(int argc, char **argv) { /* 1.日志输出到控制台 */ { log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout); appender1->setLayout(new log4cpp::BasicLayout()); // 默认配置 log4cpp::Category& root = log4cpp::Category::getRoot(); root.setPriority(log4cpp::Priority::WARN); root.addAppender(appender1); // 1.use of functions for logging messages root.debug("root debug"); root.warn("root warn"); root.error("root error"); root.info("root info"); // 2.printf-style for logging variables root.warn("%d + %d == %s ?", 1, 1, "two"); // 3.use of streams for logging messages root << log4cpp::Priority::ERROR << "Streamed root error"; root << log4cpp::Priority::INFO << "Streamed root info"; // 4.or this way: root.errorStream() << "Another streamed error"; root.debugStream() << "Another streamed debug"; } /* 2.日志输出到控制台和本地文件 */ { log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "program.log"); appender2->setLayout(new log4cpp::BasicLayout()); log4cpp::Category& sub1 = log4cpp::Category::getInstance(std::string("sub1")); sub1.addAppender(appender2); sub1.error("sub1 error"); sub1.warn("sub1 warn"); sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error"; sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn"; } /* 3.日志输出到本地文件 */ { std::string logFileName = "test.log"; // 优先级 log4cpp::Priority::PriorityLevel logPri = log4cpp::Priority::DEBUG; // 自定义布局 log4cpp::PatternLayout* logLayout = new log4cpp::PatternLayout(); logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] : %m%n"); // 日志输出到本地文件 log4cpp::FileAppender* logFile = new log4cpp::FileAppender("default", logFileName); logFile->setLayout(logLayout); // 设置自定义布局 // 输出日志的操作类 log4cpp::Category& logCat = log4cpp::Category::getInstance("logCat"); logCat.addAppender(logFile); //设置优先级 logCat.setPriority(logPri); logCat.error("测试 error"); logCat.debug("测试 debug"); logCat.warn("%d + %d == %s ?", 1, 1, "two"); logCat << log4cpp::Priority::ERROR << "Streamed root error"; logCat << log4cpp::Priority::INFO << "Streamed root info"; logCat.errorStream() << "Another streamed error"; logCat.debugStream() << "Another streamed debug"; } // 关闭日志 log4cpp::Category::shutdown(); return 0; }
编译:
g++ test_log4cpp.cpp -I ./inlcude/ -L ./lib/ -llog4cpp1 -lpthread -o test_log4cpp
log4cpp1:是log4cpp.a静态库,我将名字改成这样(在上图中可以看到),才可以正常链接到静态库;不知道为什么,链接动态库.so,编译会报错,所以只能链接静态库去完成编译运行。
-I:指定头文件路径,可以使用相对路径
-L:指定库的路径,可以使用相对路径
四、log4cpp项目用法
以下介绍的项目用法,Linux和Window环境均可使用!
一般来说,日志都是由独立的文件夹去保存的,下面为了方便就直接将日志保存在main函数同级目录了。
1. 配置文件使用log4cpp
新建项目,在项目路径下新建文件名为:log.conf
粘贴以下配置到log.conf文件中
#定义Root category的属性 log4cpp.rootCategory=DEBUG, RootLog # 优先级, 当前日志代表变量名 #定义RootLog属性 #log4cpp.appender.RootLog = FileAppender # 输出到文件 log4cpp.appender.RootLog = RollingFileAppender # 回卷 log4cpp.appender.RootLog.layout = PatternLayout # 自定义输出日志格式 # 日志输出格式 log4cpp.appender.RootLog.layout.ConversionPattern = %d{%Y-%m-%d %H:%M:%S.%l} [%t][%p] %m%n # 日志名 log4cpp.appender.RootLog.fileName = ./test.log # 单个日志文件大小 log4cpp.appender.RootLog.maxFileSize = 268435456 #256MB # 回卷日志个数名 log4cpp.appender.RootLog.fileNamePattern = test_%i.log # 日志个数 log4cpp.appender.RootLog.maxBackupIndex = 256 # append=true 信息追加到上面指定的日志文件中,false表示将信息覆盖指定文件内容 log4cpp.appender.RootLog.append = true
在项目中新建文件MyLogger.h
#ifndef _MY_LOGGER_H_ #define _MY_LOGGER_H_ #include <string> #include <log4cpp/Category.hh> class MyLogger { public: bool init(const std::string &log_conf_file); // 指定加载log配置文件 static MyLogger *instance() { return &_instance; }; // 单例模式,返回自己 log4cpp::Category *GetHandle() { return _category; }; private: static MyLogger _instance; log4cpp::Category *_category; // 通过此对象可以实现日志写入 }; /* 宏定义,方便调用 */ #define LOG_DEBUG MyLogger::instance()->GetHandle()->debug // 调试 #define LOG_INFO MyLogger::instance()->GetHandle()->info // 信息,消息 #define Log_NOTICE MyLogger::instance()->GetHandle()->notice // 通知 #define LOG_WARN MyLogger::instance()->GetHandle()->warn // 警告 #define LOG_ERROR MyLogger::instance()->GetHandle()->error // 错误 #define LOG_FATAL MyLowww.chinasem.cngger::instance()->GetHandle()->fatal // 致命错误 /* * __LINE__ : 文件中的当前行号; * __FILE__ : 文件的完整路径和文件名;如果用在包含文件中,则返回包含文件名; * __FUNCTION__ : 函数名字。 */ #define LOG(__level) log4cpp::Category::getRoot() << log4cpp::Priority::__level << "[" << __FUNCTION__ << "][" << __LINE__ << "]: " //#define LOG(__level) log4cpp::Category::getRoot() << log4cpp::Priority::__level << "[" << __FILE__ << "][" << __FUNCTION__ << "][" << __LINE__ << "]: " #endif
在项目中新建文件MyLogger.cpp
#include "MyLogger.h" #include <IOStream> #include <log4cpp/FileAppender.hh> #include <log4cpp/PatternLayout.hh> #include <log4cpp/PropertyConfigurator.hh> // 静态变量,需要在类外部初始化一下 MyLogger MyLogger::_instance; bool MyLogger::init(const std::string &log_conf_file) { try { log4cpp::PropertyConfigurator::configure(log_conf_file); // 初始化log配置文件 } catch (log4cpp::ConfigureFailure &f) { std::cerr << "load log config file " << log_conf_file.c_str() << " failed with result: " << f.what() << std::endl; return false; } // 初始化成功后,使用getRoot()获取操作日志的对象 _category = &log4cpp::Category::getRoot(); return true; }
main函数测试
#include "MyLogger.h" int main(void) { if (!MyLogger::instance()->init("log.conf")) { fprintf(stderr, "init log module failed.\n"); return -1; } LOG_DEBUG("测试 debug."); LOG_INFO("测试 inof."); Log_NOTICE("测试 notice."); LOG_WARN("测试 warnphp."); LOG_ERROR("测试 error."); LOG_FATAL("测试 fatal."); LOG_DEBUG("%d + %c == %s", 1, 'a', "1a"); LOG(DEBUG) << "123"; LOG(ERROR) << "ERROR"; // 关闭日志 log4cpp::Category::shutdown(); return 0; }
运行结果:
在运行一次项目:
Linux编译命令:(链接的是静态库)
g++ main.cpp MyLogger.h MyLogger.cpp -std=c++11 -I ./inlcude/ -L ./lib/ -llog4cpp1 -lpthread -o test_log4cpp
2. 纯代码使用log4cpp
网上找的代码,感觉挺不错的,拷贝过来做了修改,改成自己以后做项目可能会这样使用!
MyLog.h
#ifndef _MY_LOG_H_ #define _MY_LOG_H_ #include <log4cpp/Category.hh> #include <log4cpp/FileAppender.hh> #include <log4cpp/PatternLayout.hh> #include <log4cpp/PropertyConfigurator.hh> #include <log4cpp/OstreamAppender.hh> #include <log4cpp/RollingFileAppender.hh> #include <string> // 优先级 #define COUNT_PRITY log4cpp::Priority::INFO; // 控制台 #define LOG_PRITY log4cpp::Priority::DEBUG; // 本地文件 /*采用单例模式设计,包含两个category对象,一个负责输出到屏幕的信息,一个负责记录到日志的信息, 通过设置优先级差别,可以实现所有信息都记录在日志中,遇到error及以上的信息时打印到屏幕上*/ class MyLog { private: MyLog(bool b) { outToScreen = b; } ~MyLog() {} static MyLog * log; bool outToScreen;//是否输出日志信息到屏幕 static std::string _screenInfo;//屏幕日志信息 static std::string _logName;//文件日志名称 static log4cpp::Category& logCat; static log4cpp::Category& coutCat; static log4cpp::FileAppender* logFile;//文件日志输入 static log4cpp::OstreamAppender* logScreen;//屏幕日志输入 static log4cpp::RollingFileAppender *rollLogFile; /* 回卷用这个 */ static log4cpp::Priority::PriorityLevel logPri;//文件日志优先级 static log4cpp::Priority::PriorityLevel coutPri;//屏幕日志优先级 static log4cpp::PatternLayout* logLayout;//日志布局 static log4cpp::PatternLayout* screenLayout;//屏幕布局 static log4cpp::PatternLayout* logLayout2; /* 回卷用这个 */ private: // 返回当前年月日时分秒 static std::string getCurrentTime(std::string& year, std::string& month, std::string& day, std::string& hour, std::string& min, std::string& sec); public: // 初始化日志配置信息 static bool init(std::string logName = "time", bool toScreen = false); //获取日志函数,默认参数选择是否输出到屏幕 static MyLog* getLog(bool toScreen = false); //销毁日志对象 static void destoryLog(); //设置日志记录优先级 static void setPri(log4cpp::Priority::PriorityLevel coutLevel, log4cpp::Priority::PriorityLevel logLevel); //记录日志,调用参数 __LINE__ ,__FUNCTION__ void warn(const char * msg, int line = __LINE__, const char *function = "warn"); void error(const char * msg, int line = __LINE__, const char *function = "error"); void debug(const char * msg, int line = __LINE__, const char *function = "debug"); void info(const char * msg, int line = __LINE__, const char *function = "info"); }; //为避免每次调用都要填写参数__LINE__和__FUNCTION__,可以使用带参数的宏定义 #define MyLogWARN(msg) MyLog::getLog()->warn(msg,__LINE__,__FUNCTION__); #define MyLogINFO(msg) MyLog::getLog()->info(msg,__LINE__,__FUNCTION__); #define MyLogERROR(msg) MyLog::getLog()->error(msg,__LINE__,__FUNCTION__); #define MyLogDEBUG(msg) MyLog::getLog()->debug(msg,__LINE__,__FUNCTION__); #endif
MyLog.cpp
#include "MyLog.h" #include <time.h> MyLog* MyLog::log = NULL; std::string MyLog::_screenInfo = "screenInfo"; std::string MyLog::_logName = "log"; log4cpp::Category& root = log4cpp::Category::getRoot(); log4cpp::Category& MyLog::logCat = root.getInstance(MyLog::_logName); log4cpp::Category& MyLog::coutCat = root.getInstance(MyLog::_screenInfo); // 优先级 log4cpp::Priority::PriorityLevel MyLog::coutPri = COUNT_PRITY; // 控制台 log4cpp::Priority::PriorityLevel MyLog::logPri = LOG_PRITY; // 本地文件 log4cpp::PatternLayout* MyLog::logLayout = NULL; log4cpp::PatternLayout* MyLog::screenLayout = NULL; log4cpp::PatternLayout* MyLog::logLayout2 = NULL; /* 回卷用这个 */ log4cpp::FileAppender* MyLog::logFile = NULL;//文件日志输入 log4cpp::OstreamAppender* MyLog::logScreen = NULL;//屏幕日志输入 log4cpp::RollingFileAppender *MyLog::rollLogFile; /* 回卷用这个 */ bool MyLog::init(std::string logName, bool toScreen) { // 判断如果传入文件名参数为空,或为默认参数,则使用当前年月日.log作为日志文件名 if (logName.empty() || logName == "time") { std::string year, month, day, hour, min, sec; getCurrentTime(year, month, day, hour, min, sec); logName = year + month + day + ".log"; } if (MyLog::log == NULL) { MyLog::log = new MyLog(toScreen); MyLog::_logName = logName; log4cpp::Category& logCat = root.getInstance(MyLog::_logName); log4cpp::Category& coutCat = root.getInstance(MyLog::_screenInfo); logScreen = new log4cpp::OstreamAppender("logScreen", &std::cout); logFile = new log4cpp::FileAppender("logFile", MyLog::_logName); /* 然后注释这个 */ //rollLogFile = new log4cpp::RollingFileAppender("rollLogFile", MyLog::_logName, 1024*1024, 5); /* 回卷用这个 */ // 单个日志文件大小1M,5个回卷 //设置布局 MyLog::logLayout = new log4cpp::PatternLayout(); /* 然后注释这个 */ MyLog::screenLayout = new log4cpp::PatternLayout(); MyLog::logLayout2 = new log4cpp::PatternLayout(); /* 回卷用这个 */ logLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n"); screenLayout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n"); logLayout2->setConversionPattern("%d{%Y-%m-%d %H:%M:%S} [%p] %m%n"); MyLog::logScreen->setLayout(screenLayout); MyLog::logFile->setLayout(logLayout); /* 然后注释这个 */ //MyLog::rollLogFile->setLayout(logLayout2); /* 回卷用这个 */ //追加到目录 MyLog::logCat.addAppender(MyLog::logFile); /* 然后注释这个 */ //MyLog::logCat.addAppender(MyLog::rollLogFile); /* 回卷用这个 */ MyLog::coutCat.addAppender(MyLog::logScreen); //设置优先级 MyLog::logCat.setPriority(MyLog::logPri); MyLog::coutCat.setPriority(MyLog::coutPri); } MyLog::log->outToScreen = toScreen; return true; } //获取日志函数,默认参数选择是否输出到屏幕 MyLog* MyLog::getLog(bool toScreen) { MyLog::log->outToScreen = toScreen; if (NULL == MyLog::log) { printf("MyLog::log is NULL, please use MyLog::init!\n"); return NULL; } return MyLog::log; } //销毁日志对象 void MyLog::destoryLog() { log4cpp::Category::shutdown(); delete MyLog::log; } //设置日志记录优先级 void MyLog::setPri(log4cpp::Priority::PriorityLevel coutLevel, log4cpp::Priority::PriorityLevel logLevel) { MyLog::logPri = logLevel; MyLog::coutPri = coutLevel; MyLog::logCat.setPriority(MyLog::logPri); MyLog::coutCat.setPriority(MyLog::coutPri); } //记录日志,调用参数__FILE__, __LINE__ ,__FUNCTION__ void MyLog::warn(const char * msg, int line, const char *function) { char info[4096] = { 0 }; sprintf(info, "[%s][%d]: %s", function, line, msg); if (this->outToScreen) { logCat.warn(info); coutCat.warn(info); } else { logCat.warn(info); } } void MyLog::error(const char * msg, int line, const char *function) { char info[4096] = { 0 }; sprintf(info, "[%s][%d]: %s", function, line, msg); if (this->outToScreen) { logCat.error(info); coutCat.error(info); } else { logCat.error(info); } } void MyLog::debug(const char * msg, int line, const char *function) { char info[4096] = { 0 }; sprintf(info, "[%s][%d]: %s", function, line, msg); if (this->outToScreen) { logCat.debug(info); coutCat.debug(info); } else { logCat.debug(info); } } void MyLog::info(const char * msg, int line, const char *function) { char info[4096] = { 0 }; sprintf(info, "[%s][%d]: %s", function, line, msg); if (this->outToScreen) { logCat.info(info); coutCat.info(info); } else { logCat.info(info); } } std::string MyLog::getCurrentTime(std::string& year, std::string& month, std::string& day, std::string& hour, std::string& min, std::string& sec) { // 获取系统时间 - 年月日时分秒 time_t _time; struct tm* target_time; time(&_time); target_time = localtime(&_time); year = std::to_string(target_time->tm_year + 1900); month = target_time->tm_mon + 1 > 9 ? std::to_string(target_time->tm_mon + 1) : "0" + std::to_string(target_time->tm_mon + 1); day = target_time->tm_mday > 9 ? std::to_string(target_time->tm_mday) : "0" + std::to_string(target_time->tm_mday); hour = target_time->tm_hour > 9 ? std::to_string(target_time->tm_hour) : "0" + std::to_string(target_time->tm_hour); min = target_time->tm_min > 9 ? std::to_string(target_time->tm_min) : "0" + std::to_string(target_time->tm_min); sec = target_time->tm_sec > 9 ? std::to_string(target_time->tm_sec) : "0" + std::to_string(target_time->tm_sec); return year + month + day + hour + min + sec; }
main函数测试
#include "MyLog.h" int main(void) { if (!MyLog::init("")) { fprintf(stderr, "init log module failed.\n"); return -1; } MyLogWARN("警告"); MyLogINFO("信息"); MyLogERROR("错误"); MyLogDEBUG("调试"); // 关闭日志 log4cpp::Category::shutdown(); return 0; }
运行结果:
Linux编译命令:(链接的是静态库)
g++ main.cpp MyLog.h MyLog.cpp -std=c++11 -I ./inlcude/ -L ./lib/ -llog4cpp1 -lpthread -o test_log4cpp
五、总结
日志在项目中是必须使用的,如果看完此篇博客还是不太懂log4cpp日志如何使用,直接拷贝上面项目代码去到自己的项目中就可以直接使用了!
到此这篇关于C++ Log4cpp跨平台日志库使用记录(Window与Linux)的文章就介绍到这了,更多相关C++ Log4cpp内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于C++ Log4cpp跨平台日志库的使用小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!