首页 > 编程知识 正文

log4cpp详解(可变参数模板——log4cpp)

时间:2023-05-05 20:13:56 阅读:123521 作者:1746

实现log4cpp的封装,使其可以像printf一样使用,测试用例如下:

void test()

       {

              int number = 100;

              const char *pstr = "hello, log4cpp";

              LogInfo("This is an info message. number = %d, str = %sn", number, pstr);

       }

------------ Mylogger.h------------#ifndef __MYLOGGER__H__#define __MYLOGGER__H__#include <log4cpp/Category.hh>#define LOGFILENAME "test.log"using namespace log4cpp;//导入全部log4cpp的全部实体class Mylogger{public: static Mylogger *getInstance(); static void destroy(); void warn(const char * msg); void error(const char * msg); void debug(const char * msg); void info(const char * msg); template <class... Args> //不能把函数的实现写在Mylogger.cc中 //和inline一样,函数的实现和声明不能分开,否则会链接失败 void warn(const char * msg, Args... args) { _root.warn(msg, args...); } template <class... Args> void error(const char * msg, Args... args) { _root.error(msg, args...); } template <class... Args> void info(const char * msg, Args... args) { _root.info(msg, args...); } template <class... Args> void debug(const char * msg, Args... args) { _root.debug(msg, args...); }private: Mylogger(); ~Mylogger();private: static Mylogger *_pInstance; Category &_root; //引用成员必须在构造函数的初始化列表进行初始化,否则会报错};//文件名、行号、函数名相关,这里没用到不用管#define prefic(msg) string(__FILE__).append(" ").append(__FUNCTION__) .append(" ").append(std::to_string(__LINE__)) .append(":").append(msg).c_str()//##__VA_ARGS__接收可变数目的参数,当宏的调用展开时,实际的参数就传递给函数了#define logError(msg,...) Mylogger::getInstance()->error(msg,##__VA_ARGS__) #define logInfo(msg,...) Mylogger::getInstance()->info(msg,##__VA_ARGS__)#define logDebug(msg,...) Mylogger::getInstance()->debug(msg,##__VA_ARGS__)#define logWarn(msg,...) Mylogger::getInstance()->warn(msg,##__VA_ARGS__)//##的用处:当只有msg参数时,忽略后面的,号#endif------------ Mylogger.cc------------#include "Mylogger.h"#include <stdlib.h>#include <log4cpp/PatternLayout.hh>#include <log4cpp/OstreamAppender.hh>#include <log4cpp/FileAppender.hh>using std::cout;using std::endl;Mylogger * Mylogger::_pInstance=Mylogger::getInstance(); //必须在实现文件中初始化,在头文件中初始化易出现重复定义Mylogger::Mylogger():_root(Category::getRoot().getInstance("Mycat")) //获得日志记录器,记录器名为Mycat{ //设置日志的格式 //文件格式 PatternLayout *ppl1 = new PatternLayout(); ppl1->setConversionPattern("%d %c [%p] %m %n"); //终端格式 PatternLayout *ppl2 = new PatternLayout(); ppl2->setConversionPattern("%d %c [%p] %m %n"); //设置日志输出的地点 //输出到文件 FileAppender *pfa = new FileAppender("FileAppender123", LOGFILENAME); pfa->setLayout(ppl1); //输出到输出流对象 OstreamAppender *poa = new OstreamAppender("OstreamAppender1", &cout); poa->setLayout(ppl2); //绑定到记录器 _root.addAppender(poa); _root.addAppender(pfa); _root.setPriority(Priority::DEBUG); cout<<"Mylogger()"<<endl;}void Mylogger::destroy()//销毁单例对象{ if(_pInstance!=nullptr) { delete _pInstance; _pInstance=nullptr; }}Mylogger *Mylogger::getInstance()//创建单例对象{ if(_pInstance==nullptr) { _pInstance=new Mylogger(); atexit(destroy);//单例模式自动释放:注册函数,进程结束时自动调用 } return _pInstance;}Mylogger::~Mylogger(){ cout<<"~Mylogger()"<<endl; Category::shutdown();//回收日志资源}void Mylogger::info(const char *msg){ _root.info(msg);}void Mylogger::error(const char *msg){ _root.error(msg);}void Mylogger::warn(const char *msg){ _root.warn(msg);}void Mylogger::debug(const char *msg){ _root.debug(msg);}------------ test.cc-----------#include "Mylogger.h"void test() { int number = 100; const char *pstr = "hello"; logInfo("This is an info message. number = %d, str = %sn", number, pstr); logWarn("this is a warn message!n"); logError("this is a error message! str=%sn",pstr); logDebug("this is a debug message!,number=%dn",number);}int main(int argc,char *argv[]){ test(); return 0;}

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。